[Pkg-virtualbox-commits] [virtualbox] 01/01: Imported Upstream version 5.0.0~beta2-dfsg

Gianfranco Costamagna locutusofborg-guest at moszumanska.debian.org
Wed Apr 15 08:53:55 UTC 2015


This is an automated email from the git hooks/post-receive script.

locutusofborg-guest pushed a commit to annotated tag upstream/5.0.0_beta2-dfsg
in repository virtualbox.

commit 1db4d9e5e060d178296d087f6d2f1e2f0bba09ce
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date:   Wed Apr 15 00:25:27 2015 +0200

    Imported Upstream version 5.0.0~beta2-dfsg
---
 Config.kmk                                         |   24 +-
 configure.vbs                                      |    4 +-
 doc/manual/en_US/SDKRef.xml                        |  119 +-
 doc/manual/en_US/user_AdvancedTopics.xml           |   93 +-
 doc/manual/en_US/user_BasicConcepts.xml            |   39 +-
 doc/manual/en_US/user_GuestAdditions.xml           |    2 +-
 doc/manual/en_US/user_Introduction.xml             |    2 +-
 doc/manual/en_US/user_Storage.xml                  |   39 +-
 doc/manual/en_US/user_Technical.xml                |   47 +-
 doc/manual/en_US/user_VBoxManage.xml               |   58 +-
 doc/manual/user_ChangeLogImpl.xml                  |   91 +-
 include/VBox/HostServices/DragAndDropSvc.h         |    2 +-
 include/VBox/apic.h                                |    2 +-
 include/VBox/disopcode.h                           |   15 +-
 include/VBox/err.h                                 |    4 +-
 include/VBox/err.mac                               |   14 +-
 include/VBox/log.h                                 |    8 +-
 include/VBox/sup.h                                 |   21 +
 include/VBox/vmm/cpum.h                            |  124 +-
 include/VBox/vmm/cpum.mac                          |    3 +
 include/VBox/vmm/cpumctx.h                         |   12 +-
 include/VBox/vmm/em.h                              |    4 -
 include/VBox/vmm/gim.h                             |    4 +-
 include/VBox/vmm/hm.h                              |    5 +-
 include/VBox/vmm/hm_vmx.h                          |    5 -
 include/VBox/vmm/iem.h                             |   14 +
 include/VBox/vmm/vm.h                              |   12 +
 include/VBox/vmm/vmm.h                             |    3 +
 include/iprt/asm-amd64-x86.h                       |   14 +
 include/iprt/assert.h                              |    8 +-
 include/iprt/cdefs.h                               |    4 +-
 include/iprt/err.h                                 |   22 +-
 include/iprt/err.mac                               |    5 +
 include/iprt/mangling.h                            |    4 +
 include/iprt/nt/nt.h                               |    2 +-
 include/iprt/x86.mac                               |   54 +-
 src/VBox/Additions/common/crOpenGL/DD_glc.py       |    0
 src/VBox/Additions/common/crOpenGL/DD_glh.py       |    0
 src/VBox/Additions/common/crOpenGL/NULLfuncs.py    |    0
 src/VBox/Additions/common/crOpenGL/cr_gl.py        |    0
 src/VBox/Additions/common/crOpenGL/entrypoints.py  |    0
 .../Additions/common/crOpenGL/feedback/feedback.py |    0
 .../common/crOpenGL/feedback/feedback_funcs.py     |    0
 .../common/crOpenGL/feedback/feedback_state.py     |    0
 .../common/crOpenGL/feedback/feedbackspu_proto.py  |    0
 .../Additions/common/crOpenGL/getprocaddress.py    |    0
 src/VBox/Additions/common/crOpenGL/pack/pack.py    |    0
 .../common/crOpenGL/pack/packspu_beginend.py       |    0
 .../common/crOpenGL/pack/packspu_flush.py          |    0
 .../Additions/common/crOpenGL/pack/packspu_get.py  |    0
 .../common/crOpenGL/pack/packspu_proto.py          |    0
 .../common/crOpenGL/passthrough/passthrough.py     |    0
 src/VBox/Additions/common/crOpenGL/stub_common.py  |    0
 src/VBox/Additions/common/crOpenGL/tsfuncs.py      |    0
 .../common/crOpenGL/windows_getprocaddress.py      |    0
 src/VBox/Additions/x11/VBoxClient/draganddrop.cpp  |    2 +-
 src/VBox/Additions/x11/vboxvideo/Makefile.kmk      |    2 +-
 src/VBox/Additions/x11/vboxvideo/edid.c            |  175 ---
 src/VBox/Additions/x11/vboxvideo/vboxvideo.c       |   24 +-
 src/VBox/Additions/x11/vboxvideo/vboxvideo.h       |    7 +-
 src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c   |    2 +-
 src/VBox/Devices/Audio/AudioMixBuffer.cpp          |    2 +-
 src/VBox/Devices/Audio/DrvHostDSound.cpp           |   23 +-
 .../BaseTools/Source/C/PyEfiCompressor/setup.py    |    0
 .../Firmware/BaseTools/Source/C/PyUtility/setup.py |    0
 .../BaseTools/Source/Python/AutoGen/AutoGen.py     |    0
 .../BaseTools/Source/Python/AutoGen/BuildEngine.py |    0
 .../BaseTools/Source/Python/AutoGen/GenC.py        |    0
 .../BaseTools/Source/Python/AutoGen/GenDepex.py    |    0
 .../BaseTools/Source/Python/AutoGen/GenMake.py     |    0
 .../BaseTools/Source/Python/AutoGen/StrGather.py   |    0
 .../Source/Python/AutoGen/UniClassObject.py        |    0
 .../Firmware/BaseTools/Source/Python/BPDG/BPDG.py  |    0
 .../BaseTools/Source/Python/BPDG/GenVpd.py         |    0
 .../BaseTools/Source/Python/BPDG/StringTable.py    |    0
 .../BaseTools/Source/Python/Common/Database.py     |    0
 .../Source/Python/Common/DecClassObject.py         |    0
 .../BaseTools/Source/Python/Common/Dictionary.py   |    0
 .../Source/Python/Common/DscClassObject.py         |    0
 .../Source/Python/Common/EdkIIWorkspace.py         |    0
 .../Source/Python/Common/EdkIIWorkspaceBuild.py    |    0
 .../BaseTools/Source/Python/Common/EdkLogger.py    |    0
 .../BaseTools/Source/Python/Common/Expression.py   |    0
 .../Source/Python/Common/FdfClassObject.py         |    0
 .../Source/Python/Common/InfClassObject.py         |    0
 .../Source/Python/Common/MigrationUtilities.py     |    0
 .../BaseTools/Source/Python/Common/Misc.py         |    0
 .../BaseTools/Source/Python/Common/Parsing.py      |    0
 .../BaseTools/Source/Python/Common/String.py       |    0
 .../Source/Python/Common/TargetTxtClassObject.py   |    0
 .../Source/Python/Common/ToolDefClassObject.py     |    0
 .../Source/Python/CommonDataClass/ModuleClass.py   |    0
 .../Source/Python/CommonDataClass/PackageClass.py  |    0
 .../Source/Python/CommonDataClass/PlatformClass.py |    0
 .../Firmware/BaseTools/Source/Python/Ecc/CLexer.py |    0
 .../BaseTools/Source/Python/Ecc/CParser.py         |    0
 .../Firmware/BaseTools/Source/Python/Ecc/Check.py  |    0
 .../Source/Python/Ecc/CodeFragmentCollector.py     |    0
 .../BaseTools/Source/Python/Ecc/Configuration.py   |    0
 .../BaseTools/Source/Python/Ecc/Database.py        |    0
 .../Firmware/BaseTools/Source/Python/Ecc/Ecc.py    |    0
 .../BaseTools/Source/Python/Ecc/Exception.py       |    0
 .../BaseTools/Source/Python/Ecc/FileProfile.py     |    0
 .../BaseTools/Source/Python/Ecc/MetaDataParser.py  |    0
 .../Python/Ecc/MetaFileWorkspace/MetaDataTable.py  |    0
 .../Python/Ecc/MetaFileWorkspace/MetaFileParser.py |    0
 .../Python/Ecc/MetaFileWorkspace/MetaFileTable.py  |    0
 .../BaseTools/Source/Python/Ecc/Xml/__init__.py    |    0
 .../EFI/Firmware/BaseTools/Source/Python/Ecc/c.py  |    0
 .../Firmware/BaseTools/Source/Python/Eot/CLexer.py |    0
 .../BaseTools/Source/Python/Eot/CParser.py         |    0
 .../Source/Python/Eot/CodeFragmentCollector.py     |    0
 .../BaseTools/Source/Python/Eot/Database.py        |    0
 .../Firmware/BaseTools/Source/Python/Eot/Eot.py    |    0
 .../BaseTools/Source/Python/Eot/EotGlobalData.py   |    0
 .../BaseTools/Source/Python/Eot/FileProfile.py     |    0
 .../BaseTools/Source/Python/Eot/FvImage.py         |    0
 .../BaseTools/Source/Python/Eot/InfParserLite.py   |    0
 .../Firmware/BaseTools/Source/Python/Eot/Parser.py |    0
 .../EFI/Firmware/BaseTools/Source/Python/Eot/c.py  |    0
 .../Source/Python/GenFds/AprioriSection.py         |    0
 .../BaseTools/Source/Python/GenFds/Capsule.py      |    0
 .../BaseTools/Source/Python/GenFds/CapsuleData.py  |    0
 .../Source/Python/GenFds/ComponentStatement.py     |    0
 .../Source/Python/GenFds/CompressSection.py        |    0
 .../BaseTools/Source/Python/GenFds/DataSection.py  |    0
 .../BaseTools/Source/Python/GenFds/DepexSection.py |    0
 .../BaseTools/Source/Python/GenFds/EfiSection.py   |    0
 .../Firmware/BaseTools/Source/Python/GenFds/Fd.py  |    0
 .../BaseTools/Source/Python/GenFds/FdfParser.py    |    0
 .../Firmware/BaseTools/Source/Python/GenFds/Ffs.py |    0
 .../Source/Python/GenFds/FfsFileStatement.py       |    0
 .../Source/Python/GenFds/FfsInfStatement.py        |    0
 .../Firmware/BaseTools/Source/Python/GenFds/Fv.py  |    0
 .../Source/Python/GenFds/FvImageSection.py         |    0
 .../BaseTools/Source/Python/GenFds/GenFds.py       |    0
 .../Source/Python/GenFds/GenFdsGlobalVariable.py   |    0
 .../BaseTools/Source/Python/GenFds/GuidSection.py  |    0
 .../Source/Python/GenFds/OptRomFileStatement.py    |    0
 .../Source/Python/GenFds/OptRomInfStatement.py     |    0
 .../BaseTools/Source/Python/GenFds/OptionRom.py    |    0
 .../BaseTools/Source/Python/GenFds/Region.py       |    0
 .../BaseTools/Source/Python/GenFds/Rule.py         |    0
 .../Source/Python/GenFds/RuleComplexFile.py        |    0
 .../Source/Python/GenFds/RuleSimpleFile.py         |    0
 .../BaseTools/Source/Python/GenFds/Section.py      |    0
 .../BaseTools/Source/Python/GenFds/UiSection.py    |    0
 .../BaseTools/Source/Python/GenFds/VerSection.py   |    0
 .../Firmware/BaseTools/Source/Python/GenFds/Vtf.py |    0
 .../Python/GenPatchPcdTable/GenPatchPcdTable.py    |    0
 .../Source/Python/PatchPcdValue/PatchPcdValue.py   |    0
 .../Source/Python/Table/TableDataModel.py          |    0
 .../BaseTools/Source/Python/Table/TableDec.py      |    0
 .../BaseTools/Source/Python/Table/TableDsc.py      |    0
 .../Source/Python/Table/TableEotReport.py          |    0
 .../BaseTools/Source/Python/Table/TableFdf.py      |    0
 .../BaseTools/Source/Python/Table/TableFile.py     |    0
 .../BaseTools/Source/Python/Table/TableFunction.py |    0
 .../Source/Python/Table/TableIdentifier.py         |    0
 .../BaseTools/Source/Python/Table/TableInf.py      |    0
 .../BaseTools/Source/Python/Table/TablePcd.py      |    0
 .../BaseTools/Source/Python/Table/TableQuery.py    |    0
 .../BaseTools/Source/Python/Table/TableReport.py   |    0
 .../Source/Python/TargetTool/TargetTool.py         |    0
 .../Firmware/BaseTools/Source/Python/Trim/Trim.py  |    0
 .../BaseTools/Source/Python/UPT/BuildVersion.py    |    0
 .../Source/Python/UPT/Core/DependencyRules.py      |    0
 .../Python/UPT/Core/DistributionPackageClass.py    |    0
 .../BaseTools/Source/Python/UPT/Core/IpiDb.py      |    0
 .../Source/Python/UPT/Core/PackageFile.py          |    0
 .../BaseTools/Source/Python/UPT/Core/__init__.py   |    0
 .../Source/Python/UPT/GenMetaFile/GenDecFile.py    |    0
 .../Source/Python/UPT/GenMetaFile/GenInfFile.py    |    0
 .../Python/UPT/GenMetaFile/GenMetaFileMisc.py      |    0
 .../Source/Python/UPT/GenMetaFile/GenXmlFile.py    |    0
 .../Source/Python/UPT/GenMetaFile/__init__.py      |    0
 .../BaseTools/Source/Python/UPT/InstallPkg.py      |    0
 .../Source/Python/UPT/Library/CommentGenerating.py |    0
 .../Source/Python/UPT/Library/CommentParsing.py    |    0
 .../Source/Python/UPT/Library/DataType.py          |    0
 .../Python/UPT/Library/ExpressionValidate.py       |    0
 .../Source/Python/UPT/Library/GlobalData.py        |    0
 .../BaseTools/Source/Python/UPT/Library/Misc.py    |    0
 .../Source/Python/UPT/Library/ParserValidate.py    |    0
 .../BaseTools/Source/Python/UPT/Library/Parsing.py |    0
 .../BaseTools/Source/Python/UPT/Library/String.py  |    0
 .../Source/Python/UPT/Library/Xml/XmlRoutines.py   |    0
 .../Source/Python/UPT/Library/Xml/__init__.py      |    0
 .../Source/Python/UPT/Library/__init__.py          |    0
 .../BaseTools/Source/Python/UPT/Logger/Log.py      |    0
 .../Source/Python/UPT/Logger/StringTable.py        |    0
 .../BaseTools/Source/Python/UPT/Logger/__init__.py |    0
 .../Firmware/BaseTools/Source/Python/UPT/MkPkg.py  |    0
 .../Source/Python/UPT/Object/POM/CommonObject.py   |    0
 .../Source/Python/UPT/Object/POM/ModuleObject.py   |    0
 .../Source/Python/UPT/Object/POM/PackageObject.py  |    0
 .../Source/Python/UPT/Object/POM/__init__.py       |    0
 .../Source/Python/UPT/Object/Parser/DecObject.py   |    0
 .../Python/UPT/Object/Parser/InfBinaryObject.py    |    0
 .../UPT/Object/Parser/InfBuildOptionObject.py      |    0
 .../UPT/Object/Parser/InfDefineCommonObject.py     |    0
 .../Python/UPT/Object/Parser/InfDefineObject.py    |    0
 .../Python/UPT/Object/Parser/InfDepexObject.py     |    0
 .../Python/UPT/Object/Parser/InfGuidObject.py      |    0
 .../UPT/Object/Parser/InfLibraryClassesObject.py   |    0
 .../Source/Python/UPT/Object/Parser/InfMisc.py     |    0
 .../Python/UPT/Object/Parser/InfPackagesObject.py  |    0
 .../Python/UPT/Object/Parser/InfPcdObject.py       |    0
 .../Python/UPT/Object/Parser/InfPpiObject.py       |    0
 .../Python/UPT/Object/Parser/InfProtocolObject.py  |    0
 .../Python/UPT/Object/Parser/InfSoucesObject.py    |    0
 .../UPT/Object/Parser/InfUserExtensionObject.py    |    0
 .../Source/Python/UPT/Object/Parser/__init__.py    |    0
 .../BaseTools/Source/Python/UPT/Object/__init__.py |    0
 .../Source/Python/UPT/Parser/DecParser.py          |    0
 .../Source/Python/UPT/Parser/DecParserMisc.py      |    0
 .../Source/Python/UPT/Parser/InfAsBuiltProcess.py  |    0
 .../Python/UPT/Parser/InfBinarySectionParser.py    |    0
 .../UPT/Parser/InfBuildOptionSectionParser.py      |    0
 .../Python/UPT/Parser/InfDefineSectionParser.py    |    0
 .../Python/UPT/Parser/InfDepexSectionParser.py     |    0
 .../UPT/Parser/InfGuidPpiProtocolSectionParser.py  |    0
 .../Python/UPT/Parser/InfLibrarySectionParser.py   |    0
 .../Python/UPT/Parser/InfPackageSectionParser.py   |    0
 .../Source/Python/UPT/Parser/InfParser.py          |    0
 .../Source/Python/UPT/Parser/InfParserMisc.py      |    0
 .../Python/UPT/Parser/InfPcdSectionParser.py       |    0
 .../Source/Python/UPT/Parser/InfSectionParser.py   |    0
 .../Python/UPT/Parser/InfSourceSectionParser.py    |    0
 .../BaseTools/Source/Python/UPT/Parser/__init__.py |    0
 .../Python/UPT/PomAdapter/DecPomAlignment.py       |    0
 .../Python/UPT/PomAdapter/InfPomAlignment.py       |    0
 .../Python/UPT/PomAdapter/InfPomAlignmentMisc.py   |    0
 .../Source/Python/UPT/PomAdapter/__init__.py       |    0
 .../Firmware/BaseTools/Source/Python/UPT/RmPkg.py  |    0
 .../Firmware/BaseTools/Source/Python/UPT/UPT.py    |    0
 .../UPT/UnitTest/CommentGeneratingUnitTest.py      |    0
 .../Python/UPT/UnitTest/CommentParsingUnitTest.py  |    0
 .../Source/Python/UPT/UnitTest/DecParserTest.py    |    0
 .../Python/UPT/UnitTest/DecParserUnitTest.py       |    0
 .../Python/UPT/UnitTest/InfBinarySectionTest.py    |    0
 .../BaseTools/Source/Python/UPT/Xml/CommonXml.py   |    0
 .../Source/Python/UPT/Xml/GuidProtocolPpiXml.py    |    0
 .../BaseTools/Source/Python/UPT/Xml/IniToXml.py    |    0
 .../Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py  |    0
 .../Source/Python/UPT/Xml/PackageSurfaceAreaXml.py |    0
 .../BaseTools/Source/Python/UPT/Xml/PcdXml.py      |    0
 .../BaseTools/Source/Python/UPT/Xml/XmlParser.py   |    0
 .../Source/Python/UPT/Xml/XmlParserMisc.py         |    0
 .../BaseTools/Source/Python/UPT/Xml/__init__.py    |    0
 .../Source/Python/Workspace/BuildClassObject.py    |    0
 .../Source/Python/Workspace/MetaDataTable.py       |    0
 .../Source/Python/Workspace/MetaFileParser.py      |    0
 .../Source/Python/Workspace/MetaFileTable.py       |    0
 .../Source/Python/Workspace/WorkspaceDatabase.py   |    0
 .../BaseTools/Source/Python/build/BuildReport.py   |    0
 .../BaseTools/Source/Python/build/build.py         |    0
 src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd      |  Bin 1048576 -> 1048576 bytes
 src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd      |  Bin 1048576 -> 1048576 bytes
 src/VBox/Devices/Graphics/BIOS/Makefile.kmk        |    4 +-
 .../Graphics/BIOS/VBoxVgaBiosAlternative.asm       |  865 +++++------
 .../Graphics/BIOS/VBoxVgaBiosAlternative.md5sum    |    2 +-
 src/VBox/Devices/Input/PS2M.cpp                    |    2 +-
 src/VBox/Devices/Makefile.kmk                      |    1 +
 src/VBox/Devices/Network/slirp/bsd/sys/mbuf.h      |    2 +-
 .../Devices/Network/slirp/resolv_conf_parser.c     |    4 +
 src/VBox/Devices/Network/slirp/slirp_dns.c         |    2 +-
 src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm   | 1275 ++++++++--------
 .../Devices/PC/BIOS/VBoxBiosAlternative.md5sum     |    2 +-
 src/VBox/Devices/PC/BIOS/ahci.c                    |   46 +-
 src/VBox/Devices/PC/BIOS/scsi.c                    |   29 +-
 src/VBox/Devices/PC/DevPcBios.cpp                  |    6 +-
 .../PC/ipxe/src/arch/i386/prefix/romprefix.S       |    6 +-
 src/VBox/Devices/Serial/DrvTCP.cpp                 |  492 +++++++
 src/VBox/Devices/build/VBoxDD.cpp                  |    5 +-
 src/VBox/Devices/build/VBoxDD.h                    |    3 +-
 src/VBox/Disassembler/DisasmTables.cpp             |    4 +-
 .../VBoxDTrace/onnv/cmd/dtrace/demo/mkdemo.pl      |    0
 .../dtrace/test/tst/common/funcs/tst.index.d.out   |    0
 .../dtrace/test/tst/common/funcs/tst.substr.d.out  |    0
 .../dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh |    0
 .../dtrace/test/tst/common/ip/tst.ipv4localudp.ksh |    0
 .../test/tst/common/ip/tst.ipv4remotetcp.ksh       |    0
 .../test/tst/common/ip/tst.ipv4remoteudp.ksh       |    0
 .../test/tst/common/ip/tst.localtcpstate.ksh       |    0
 .../test/tst/common/ip/tst.remotetcpstate.ksh      |    0
 .../scripting/err.D_MACRO_UNDEF.invalidargs.d      |    0
 .../tst/common/scripting/err.D_OP_LVAL.rdonly.d    |    0
 .../common/scripting/err.D_OP_WRITE.usepidmacro.d  |    0
 .../test/tst/common/scripting/err.D_SYNTAX.inval.d |    0
 .../test/tst/common/scripting/err.D_SYNTAX.pid.d   |    0
 .../dtrace/test/tst/common/scripting/tst.arg0.d    |    0
 .../dtrace/test/tst/common/scripting/tst.assign.d  |    0
 .../dtrace/test/tst/common/scripting/tst.basic.d   |    0
 .../dtrace/test/tst/common/scripting/tst.egid.d    |    0
 .../dtrace/test/tst/common/scripting/tst.euid.d    |    0
 .../cmd/dtrace/test/tst/common/scripting/tst.gid.d |    0
 .../dtrace/test/tst/common/scripting/tst.pgid.d    |    0
 .../cmd/dtrace/test/tst/common/scripting/tst.pid.d |    0
 .../dtrace/test/tst/common/scripting/tst.ppid.d    |    0
 .../dtrace/test/tst/common/scripting/tst.projid.d  |    0
 .../dtrace/test/tst/common/scripting/tst.quite.d   |    0
 .../cmd/dtrace/test/tst/common/scripting/tst.sid.d |    0
 .../dtrace/test/tst/common/scripting/tst.taskid.d  |    0
 .../dtrace/test/tst/common/scripting/tst.trace.d   |    0
 .../cmd/dtrace/test/tst/common/scripting/tst.uid.d |    0
 .../err.D_ACT_SPEC.SpeculateWithBreakPoint.d       |    0
 .../err.D_ACT_SPEC.SpeculateWithChill.d            |    0
 .../err.D_ACT_SPEC.SpeculateWithCopyOut.d          |    0
 .../err.D_ACT_SPEC.SpeculateWithCopyOutStr.d       |    0
 .../err.D_ACT_SPEC.SpeculateWithPanic.d            |    0
 .../err.D_ACT_SPEC.SpeculateWithRaise.d            |    0
 .../speculation/err.D_ACT_SPEC.SpeculateWithStop.d |    0
 .../dtrace/test/tst/common/usdt/tst.corruptenv.ksh |    0
 .../onnv/lib/libdtrace/common/mkerrtags.sh         |    0
 .../Frontends/VBoxAutostart/VBoxAutostartStop.cpp  |    4 +-
 .../Frontends/VBoxAutostart/VBoxAutostartUtils.cpp |   20 +-
 .../VBoxBalloonCtrl/VBoxModAPIMonitor.cpp          |    8 +-
 src/VBox/Frontends/VBoxManage/VBoxManage.cpp       |   42 +
 src/VBox/Frontends/VBoxManage/VBoxManage.h         |    1 +
 .../Frontends/VBoxManage/VBoxManageAppliance.cpp   |   27 +
 .../Frontends/VBoxManage/VBoxManageControlVM.cpp   |    4 +-
 src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp   |   57 +-
 src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp   |    5 +-
 src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp   |   38 +-
 src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp   |   49 +-
 .../Frontends/VBoxManage/VBoxManageModifyVM.cpp    |  394 ++---
 .../Frontends/VBoxManage/VBoxManageSnapshot.cpp    |   59 +-
 src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp             |   14 +-
 src/VBox/Frontends/VBoxShell/vboxshell.py          |   20 +-
 src/VBox/Frontends/VirtualBox/Makefile.kmk         |    2 +-
 .../Frontends/VirtualBox/src/UIVMInfoDialog.cpp    |    2 +-
 .../VirtualBox/src/converter/UIConverterBackend.h  |    9 +-
 .../src/converter/UIConverterBackendCOM.cpp        |   24 +-
 .../src/converter/UIConverterBackendGlobal.cpp     |   91 +-
 .../src/extensions/QIStyledItemDelegate.h          |   24 +-
 .../VirtualBox/src/extradata/UIExtraDataDefs.cpp   |    3 +-
 .../VirtualBox/src/extradata/UIExtraDataDefs.h     |   49 +-
 .../src/extradata/UIExtraDataManager.cpp           |   17 +-
 .../VirtualBox/src/extradata/UIExtraDataManager.h  |   12 +-
 .../VirtualBox/src/globals/UIActionPool.cpp        |  202 +--
 .../VirtualBox/src/globals/UIActionPool.h          |   29 +-
 .../VirtualBox/src/globals/UIMessageCenter.cpp     |   43 +-
 .../VirtualBox/src/globals/UIMessageCenter.h       |   12 +-
 .../VirtualBox/src/globals/VBoxGlobal.cpp          |    3 +-
 .../Frontends/VirtualBox/src/medium/UIMedium.cpp   |  452 +++---
 .../Frontends/VirtualBox/src/medium/UIMedium.h     |  354 +++--
 .../VirtualBox/src/runtime/UIActionPoolRuntime.cpp |   66 +-
 .../VirtualBox/src/runtime/UIActionPoolRuntime.h   |    3 -
 .../runtime/UIAddDiskEncryptionPasswordDialog.cpp  |   51 +-
 .../runtime/UIAddDiskEncryptionPasswordDialog.h    |    3 +
 .../VirtualBox/src/runtime/UIDnDMIMEData.cpp       |    2 +-
 .../VirtualBox/src/runtime/UIFrameBuffer.cpp       |   83 +-
 .../VirtualBox/src/runtime/UIFrameBuffer.h         |   11 +-
 .../Frontends/VirtualBox/src/runtime/UIMachine.cpp |    8 +-
 .../VirtualBox/src/runtime/UIMachineLogic.cpp      |  123 +-
 .../VirtualBox/src/runtime/UIMachineView.cpp       |   16 +
 .../VirtualBox/src/runtime/UIMachineView.h         |    3 +
 .../src/runtime/UIMenuBarEditorWindow.cpp          |   37 +-
 .../VirtualBox/src/runtime/UIMenuBarEditorWindow.h |    8 +-
 .../Frontends/VirtualBox/src/runtime/UISession.cpp |   52 +-
 .../fullscreen/UIMachineWindowFullscreen.cpp       |    2 +-
 .../runtime/seamless/UIMachineWindowSeamless.cpp   |    2 +-
 .../VirtualBox/src/selector/UISelectorWindow.cpp   |   60 +-
 .../VirtualBox/src/selector/VBoxSnapshotsWgt.cpp   |  145 +-
 .../graphics/chooser/UIGChooserItemMachine.cpp     |    1 +
 .../graphics/details/UIGDetailsElements.cpp        |   15 +-
 .../settings/machine/UIMachineSettingsGeneral.cpp  |    2 -
 .../src/settings/machine/UIMachineSettingsSF.cpp   |    2 +-
 .../settings/machine/UIMachineSettingsSerial.cpp   |    9 +-
 .../settings/machine/UIMachineSettingsSerial.ui    |   15 +-
 .../VirtualBox/src/widgets/UIFilmContainer.cpp     |    0
 .../src/wizards/clonevm/UIWizardCloneVM.cpp        |   12 +-
 src/VBox/GuestHost/OpenGL/error/error.py           |    0
 src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py  |    0
 src/VBox/GuestHost/OpenGL/packer/pack_current.py   |    0
 .../GuestHost/OpenGL/packer/pack_currentheader.py  |    0
 src/VBox/GuestHost/OpenGL/packer/pack_header.py    |    0
 src/VBox/GuestHost/OpenGL/packer/packer.py         |    0
 src/VBox/GuestHost/OpenGL/packer/packer_bbox.py    |    0
 src/VBox/GuestHost/OpenGL/spu_loader/dispatch.py   |    0
 .../GuestHost/OpenGL/spu_loader/dispatchheader.py  |    0
 src/VBox/GuestHost/OpenGL/spu_loader/glloader.py   |    0
 src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py  |    0
 src/VBox/GuestHost/OpenGL/spu_loader/spucopy.py    |    0
 src/VBox/GuestHost/OpenGL/state_tracker/convert.py |    0
 .../GuestHost/OpenGL/state_tracker/dump_gen.py     |    0
 .../OpenGL/state_tracker/state_current.py          |    0
 .../GuestHost/OpenGL/state_tracker/state_defs.py   |    0
 .../GuestHost/OpenGL/state_tracker/state_diff.c    |   14 +-
 .../GuestHost/OpenGL/state_tracker/state_funcs.py  |    0
 .../GuestHost/OpenGL/state_tracker/state_get.py    |    0
 .../OpenGL/state_tracker/state_isenabled.py        |    0
 src/VBox/GuestHost/OpenGL/util/debug_opcodes.py    |    0
 src/VBox/HostDrivers/Support/SUPLibAll.cpp         |    2 +-
 src/VBox/HostDrivers/Support/freebsd/Makefile      |    3 +
 src/VBox/HostDrivers/Support/freebsd/files_vboxdrv |    2 +
 .../VBoxNetFlt/win/ndis6/VBoxNetLwf-win.cpp        |   27 +
 .../HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp    |   12 +-
 src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h  |   12 -
 .../HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp     |   42 +-
 .../HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp     |    2 -
 .../testcase/tstSharedFolderService.cpp            |    1 +
 .../SharedOpenGL/crserverlib/server_dispatch.py    |    0
 .../crserverlib/server_dispatch_header.py          |    0
 .../SharedOpenGL/crserverlib/server_get.py         |    0
 .../SharedOpenGL/crserverlib/server_main.c         |    5 +-
 .../SharedOpenGL/crserverlib/server_retval.py      |    0
 .../SharedOpenGL/crserverlib/server_simpleget.py   |    0
 .../HostServices/SharedOpenGL/expando/expando.py   |    0
 .../HostServices/SharedOpenGL/unpacker/unpack.py   |    0
 .../SharedOpenGL/unpacker/unpack_extend.py         |    0
 .../SharedOpenGL/unpacker/unpack_header.py         |    0
 src/VBox/Installer/common/virtualbox.desktop.in    |    3 +
 src/VBox/Installer/linux/distributions_deb         |    4 +-
 src/VBox/Installer/linux/vboxdrv-pardus.py         |    0
 src/VBox/Installer/win/VirtualBox.wxs              |   21 +
 src/VBox/Main/Makefile.kmk                         |    5 +-
 src/VBox/Main/glue/vboxapi.py                      |    0
 src/VBox/Main/idl/VirtualBox.xidl                  | 1551 ++++++++++----------
 src/VBox/Main/include/ApplianceImpl.h              |    3 +
 src/VBox/Main/include/ApplianceImplPrivate.h       |   10 +
 src/VBox/Main/include/ConsoleImpl.h                |   76 +-
 src/VBox/Main/include/DisplayImpl.h                |    7 +-
 src/VBox/Main/include/Global.h                     |   43 -
 src/VBox/Main/include/MachineImpl.h                |  179 ++-
 src/VBox/Main/include/MediumImpl.h                 |    4 +
 src/VBox/Main/include/SecretKeyStore.h             |  189 +++
 src/VBox/Main/include/SessionImpl.h                |   22 +-
 src/VBox/Main/include/VirtualBoxErrorInfoImpl.h    |   27 +-
 src/VBox/Main/include/VirtualBoxImpl.h             |    1 +
 src/VBox/Main/src-all/Global.cpp                   |    5 +-
 src/VBox/Main/src-all/ProgressImpl.cpp             |    4 +-
 src/VBox/Main/src-all/SecretKeyStore.cpp           |  228 +++
 src/VBox/Main/src-all/win/comregister.cmd          |    5 +-
 src/VBox/Main/src-client/ConsoleImpl.cpp           | 1528 ++++++-------------
 src/VBox/Main/src-client/ConsoleImpl2.cpp          |   22 +-
 src/VBox/Main/src-client/ConsoleImplTeleporter.cpp |    4 +-
 src/VBox/Main/src-client/DisplayImpl.cpp           |   17 +-
 src/VBox/Main/src-client/DrvAudioVRDE.cpp          |    3 +
 src/VBox/Main/src-client/GuestDnDPrivate.cpp       |    6 +-
 src/VBox/Main/src-client/GuestDnDSourceImpl.cpp    |    4 +-
 src/VBox/Main/src-client/GuestDnDTargetImpl.cpp    |    5 +-
 src/VBox/Main/src-client/GuestImpl.cpp             |    2 +-
 src/VBox/Main/src-client/SessionImpl.cpp           |  100 +-
 src/VBox/Main/src-server/ApplianceImpl.cpp         |   51 +
 src/VBox/Main/src-server/ApplianceImplExport.cpp   |   28 +
 src/VBox/Main/src-server/HostDnsService.cpp        |  100 +-
 src/VBox/Main/src-server/HostDnsService.h          |   63 +-
 .../Main/src-server/HostDnsServiceResolvConf.cpp   |    4 +-
 src/VBox/Main/src-server/HostImpl.cpp              |   84 +-
 src/VBox/Main/src-server/HostPower.cpp             |   18 +-
 src/VBox/Main/src-server/MachineImpl.cpp           | 1048 +++++++------
 src/VBox/Main/src-server/MediumImpl.cpp            |  102 +-
 src/VBox/Main/src-server/Performance.cpp           |    4 +-
 src/VBox/Main/src-server/SerialPortImpl.cpp        |   10 +-
 src/VBox/Main/src-server/SnapshotImpl.cpp          |  949 +++++++-----
 src/VBox/Main/src-server/VirtualBoxImpl.cpp        |   22 +-
 .../src-server/darwin/HostDnsServiceDarwin.cpp     |    8 +-
 .../src-server/freebsd/HostHardwareFreeBSD.cpp     |    1 +
 .../src-server/freebsd/USBProxyServiceFreeBSD.cpp  |    8 +-
 src/VBox/Main/src-server/win/HostDnsServiceWin.cpp |   59 +-
 src/VBox/Main/xml/Settings.cpp                     |   50 +-
 src/VBox/Main/xml/VirtualBox-settings.xsd          |    3 +-
 src/VBox/RDP/{client => client-1.8.3}/COPYING      |    0
 src/VBox/RDP/{client => client-1.8.3}/Makefile.in  |   13 +-
 src/VBox/RDP/{client => client-1.8.3}/Makefile.kmk |   17 +-
 src/VBox/RDP/{client => client-1.8.3}/README       |    0
 src/VBox/RDP/client-1.8.3/asn.c                    |  118 ++
 src/VBox/RDP/{client => client-1.8.3}/bitmap.c     |    0
 src/VBox/RDP/{client => client-1.8.3}/bootstrap    |    0
 src/VBox/RDP/{client => client-1.8.3}/cache.c      |    0
 src/VBox/RDP/{client => client-1.8.3}/channels.c   |    6 +-
 src/VBox/RDP/{client => client-1.8.3}/cliprdr.c    |    2 +-
 src/VBox/RDP/{client => client-1.8.3}/config.guess |    0
 src/VBox/RDP/{client => client-1.8.3}/config.sub   |    0
 src/VBox/RDP/{client => client-1.8.3}/configure    | 1409 ++++++++++++++----
 src/VBox/RDP/{client => client-1.8.3}/configure.ac |  175 ++-
 src/VBox/RDP/{client => client-1.8.3}/constants.h  |  114 +-
 src/VBox/RDP/client-1.8.3/cssp.c                   |  918 ++++++++++++
 src/VBox/RDP/client-1.8.3/ctrl.c                   |  528 +++++++
 src/VBox/RDP/{client => client-1.8.3}/disk.c       |   36 +-
 src/VBox/RDP/{client => client-1.8.3}/disk.h       |    0
 src/VBox/RDP/{client => client-1.8.3}/doc/AUTHORS  |    0
 .../RDP/{client => client-1.8.3}/doc/ChangeLog     |   77 +
 src/VBox/RDP/{client => client-1.8.3}/doc/HACKING  |    0
 src/VBox/RDP/{client => client-1.8.3}/doc/TODO     |    0
 src/VBox/RDP/{client => client-1.8.3}/doc/ipv6.txt |    0
 .../{client => client-1.8.3}/doc/keymap-names.txt  |    0
 .../{client => client-1.8.3}/doc/keymapping.txt    |    0
 .../RDP/{client => client-1.8.3}/doc/licensing.txt |    0
 .../RDP/{client => client-1.8.3}/doc/patches.txt   |    0
 .../RDP/{client => client-1.8.3}/doc/rdesktop.1    |   67 +-
 .../{client => client-1.8.3}/doc/redirection.txt   |    0
 src/VBox/RDP/{client => client-1.8.3}/ewmhints.c   |   38 +-
 src/VBox/RDP/{client => client-1.8.3}/install-sh   |    0
 src/VBox/RDP/{client => client-1.8.3}/iso.c        |  178 ++-
 src/VBox/RDP/{client => client-1.8.3}/keymaps/ar   |    0
 .../RDP/{client => client-1.8.3}/keymaps/common    |    0
 .../{client => client-1.8.3}/keymaps/convert-map   |    3 +-
 src/VBox/RDP/client-1.8.3/keymaps/cs               |  187 +++
 src/VBox/RDP/{client => client-1.8.3}/keymaps/da   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/de   |    0
 .../RDP/{client => client-1.8.3}/keymaps/de-ch     |    0
 .../RDP/{client => client-1.8.3}/keymaps/en-dv     |    0
 .../RDP/{client => client-1.8.3}/keymaps/en-gb     |    0
 .../RDP/{client => client-1.8.3}/keymaps/en-us     |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/es   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/et   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/fi   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/fo   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/fr   |    0
 .../RDP/{client => client-1.8.3}/keymaps/fr-be     |    0
 .../RDP/{client => client-1.8.3}/keymaps/fr-ca     |    0
 .../RDP/{client => client-1.8.3}/keymaps/fr-ch     |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/he   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/hr   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/hu   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/is   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/it   |    6 +-
 src/VBox/RDP/{client => client-1.8.3}/keymaps/ja   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/ko   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/lt   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/lv   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/mk   |    0
 .../RDP/{client => client-1.8.3}/keymaps/modifiers |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/nl   |    2 +-
 .../RDP/{client => client-1.8.3}/keymaps/nl-be     |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/no   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/pl   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/pt   |    0
 .../RDP/{client => client-1.8.3}/keymaps/pt-br     |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/ru   |    0
 src/VBox/RDP/client-1.8.3/keymaps/sk               |  189 +++
 src/VBox/RDP/{client => client-1.8.3}/keymaps/sl   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/sv   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/th   |    0
 src/VBox/RDP/{client => client-1.8.3}/keymaps/tr   |    0
 src/VBox/RDP/{client => client-1.8.3}/licence.c    |  189 ++-
 src/VBox/RDP/{client => client-1.8.3}/lspci.c      |    0
 src/VBox/RDP/{client => client-1.8.3}/mcs.c        |   77 +-
 src/VBox/RDP/{client => client-1.8.3}/mppc.c       |    0
 src/VBox/RDP/{client => client-1.8.3}/orders.c     |    4 +-
 src/VBox/RDP/{client => client-1.8.3}/orders.h     |    0
 src/VBox/RDP/{client => client-1.8.3}/parallel.c   |    0
 src/VBox/RDP/{client => client-1.8.3}/parse.h      |    3 +
 src/VBox/RDP/{client => client-1.8.3}/printer.c    |    2 +-
 .../RDP/{client => client-1.8.3}/printercache.c    |   29 +-
 src/VBox/RDP/{client => client-1.8.3}/proto.h      |   48 +-
 src/VBox/RDP/{client => client-1.8.3}/proto.head   |    0
 src/VBox/RDP/{client => client-1.8.3}/proto.tail   |    0
 src/VBox/RDP/{client => client-1.8.3}/pstcache.c   |    0
 src/VBox/RDP/{client => client-1.8.3}/rdesktop.c   |  366 ++++-
 src/VBox/RDP/{client => client-1.8.3}/rdesktop.h   |    4 +
 .../RDP/{client => client-1.8.3}/rdesktop.spec     |    4 +-
 src/VBox/RDP/{client => client-1.8.3}/rdp.c        |  363 +++--
 src/VBox/RDP/{client => client-1.8.3}/rdp5.c       |    2 +-
 src/VBox/RDP/{client => client-1.8.3}/rdpdr.c      |  188 +--
 src/VBox/RDP/{client => client-1.8.3}/rdpsnd.c     |   22 +-
 src/VBox/RDP/{client => client-1.8.3}/rdpsnd.h     |    0
 .../RDP/{client => client-1.8.3}/rdpsnd_alsa.c     |    0
 src/VBox/RDP/{client => client-1.8.3}/rdpsnd_dsp.c |    2 +-
 src/VBox/RDP/{client => client-1.8.3}/rdpsnd_dsp.h |    0
 .../RDP/{client => client-1.8.3}/rdpsnd_libao.c    |    4 +-
 src/VBox/RDP/{client => client-1.8.3}/rdpsnd_oss.c |    0
 src/VBox/RDP/{client => client-1.8.3}/rdpsnd_sgi.c |    0
 src/VBox/RDP/{client => client-1.8.3}/rdpsnd_sun.c |    0
 src/VBox/RDP/{client => client-1.8.3}/scancodes.h  |    0
 src/VBox/RDP/{client => client-1.8.3}/scard.c      |  421 ++++--
 src/VBox/RDP/{client => client-1.8.3}/scard.h      |    6 +-
 src/VBox/RDP/{client => client-1.8.3}/seamless.c   |   47 +-
 src/VBox/RDP/{client => client-1.8.3}/seamless.h   |    2 +-
 src/VBox/RDP/{client => client-1.8.3}/secure.c     |  330 +++--
 src/VBox/RDP/{client => client-1.8.3}/serial.c     |   16 +-
 src/VBox/RDP/{client => client-1.8.3}/ssl.c        |   53 +-
 src/VBox/RDP/{client => client-1.8.3}/ssl.h        |   58 +-
 src/VBox/RDP/{client => client-1.8.3}/tcp.c        |  285 +++-
 src/VBox/RDP/{client => client-1.8.3}/types.h      |   20 +
 src/VBox/RDP/client-1.8.3/utils.c                  |  233 +++
 .../RDP/{client => client-1.8.3}/vrdp/rdpusb.c     |    0
 .../RDP/{client => client-1.8.3}/vrdp/vrdpusb.h    |    0
 src/VBox/RDP/{client => client-1.8.3}/xclip.c      |    4 +-
 src/VBox/RDP/{client => client-1.8.3}/xkeymap.c    |  145 +-
 src/VBox/RDP/{client => client-1.8.3}/xproto.h     |    1 +
 src/VBox/RDP/{client => client-1.8.3}/xwin.c       |   98 +-
 src/VBox/RDP/client/keymaps/cs                     |   87 --
 src/VBox/Runtime/Makefile.kmk                      |   10 +-
 src/VBox/Runtime/VBox/VBoxRTDeps.cpp               |    1 +
 src/VBox/Runtime/common/alloc/memcache.cpp         |  150 +-
 .../common/asm/ASMGetXcr0.asm}                     |   63 +-
 .../common/asm/ASMSetXcr0.asm}                     |   74 +-
 .../Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c   |    8 +
 .../Runtime/r0drv/linux/initterm-r0drv-linux.c     |    4 +
 src/VBox/Runtime/r3/freebsd/systemmem-freebsd.cpp  |   98 ++
 src/VBox/Runtime/r3/win/process-win.cpp            |    4 +-
 src/VBox/Storage/testcase/BuiltinTests.h           |    4 +-
 src/VBox/Storage/testcase/Makefile.kmk             |    2 +-
 src/VBox/Storage/testcase/tstVDIo.cpp              |   10 +-
 src/VBox/VMM/VMMAll/CPUMAllRegs.cpp                |   63 +-
 src/VBox/VMM/VMMAll/EMAll.cpp                      |   69 +-
 src/VBox/VMM/VMMAll/GIMAll.cpp                     |   20 +-
 src/VBox/VMM/VMMAll/GIMAllKvm.cpp                  |   94 +-
 src/VBox/VMM/VMMAll/HMAll.cpp                      |   74 +-
 src/VBox/VMM/VMMAll/IEMAll.cpp                     |  220 +--
 src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h              |   51 +-
 src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h       |   29 +-
 src/VBox/VMM/VMMAll/VMMAll.cpp                     |   74 +
 src/VBox/VMM/VMMR0/CPUMR0A.asm                     |  537 ++++---
 src/VBox/VMM/VMMR0/HMR0.cpp                        |   10 +-
 src/VBox/VMM/VMMR0/HMSVMR0.cpp                     |   54 +-
 src/VBox/VMM/VMMR0/HMVMXR0.cpp                     |  220 ++-
 src/VBox/VMM/VMMR3/CPUM.cpp                        |   28 +-
 src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp                 |  292 +++-
 src/VBox/VMM/VMMR3/GIM.cpp                         |    1 -
 src/VBox/VMM/VMMR3/GIMHv.cpp                       |   44 +-
 src/VBox/VMM/VMMR3/GIMKvm.cpp                      |   27 +-
 src/VBox/VMM/VMMR3/HM.cpp                          |    7 +-
 src/VBox/VMM/VMMR3/IEMR3.cpp                       |    9 -
 src/VBox/VMM/VMMR3/PDMBlkCache.cpp                 |   21 +-
 src/VBox/VMM/VMMR3/PGM.cpp                         |    4 +-
 src/VBox/VMM/VMMR3/PGMPool.cpp                     |    4 +-
 src/VBox/VMM/VMMR3/TM.cpp                          |   13 +-
 src/VBox/VMM/VMMR3/VMM.cpp                         |    2 +-
 src/VBox/VMM/VMMR3/VMMSwitcher.cpp                 |    6 +-
 src/VBox/VMM/VMMRC/CPUMRCA.asm                     |   17 +
 src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp              |   15 +-
 src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac        |   33 +-
 src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac        |   28 +-
 src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac           |   29 +-
 src/VBox/VMM/include/CPUMInternal.h                |  150 +-
 src/VBox/VMM/include/CPUMInternal.mac              |   76 +-
 src/VBox/VMM/include/GIMKvmInternal.h              |   14 +-
 src/VBox/VMM/include/HMInternal.h                  |   34 +-
 src/VBox/VMM/include/IEMInternal.h                 |   10 -
 src/VBox/VMM/testcase/tstIEMCheckMc.cpp            |    8 +-
 src/VBox/VMM/testcase/tstX86-FpuSaveRestoreA.asm   |    8 +-
 .../bootsectors/bootsector2-first.mac              |    2 +-
 src/VBox/ValidationKit/common/__init__.py          |    0
 .../ValidationKit/common/constants/__init__.py     |    0
 src/VBox/ValidationKit/common/constants/result.py  |    0
 .../ValidationKit/common/constants/rtexitcode.py   |    0
 src/VBox/ValidationKit/common/constants/tbreq.py   |    0
 src/VBox/ValidationKit/common/constants/tbresp.py  |    0
 .../ValidationKit/common/constants/valueunit.py    |    0
 src/VBox/ValidationKit/common/utils.py             |    0
 src/VBox/ValidationKit/common/webutils.py          |    0
 src/VBox/ValidationKit/testanalysis/__init__.py    |    0
 src/VBox/ValidationKit/testanalysis/diff.py        |    0
 src/VBox/ValidationKit/testboxscript/setup.sh      |    0
 .../ValidationKit/testboxscript/testboxcommand.py  |    0
 .../ValidationKit/testboxscript/testboxcommons.py  |    0
 .../testboxscript/testboxconnection.py             |    0
 .../ValidationKit/testboxscript/testboxtasks.py    |    0
 .../ValidationKit/testboxscript/testboxupgrade.py  |    0
 src/VBox/ValidationKit/testdriver/__init__.py      |    0
 src/VBox/ValidationKit/testdriver/base.py          |    0
 src/VBox/ValidationKit/testdriver/reporter.py      |    0
 src/VBox/ValidationKit/testdriver/tst-txsclient.py |    0
 src/VBox/ValidationKit/testdriver/txsclient.py     |    0
 src/VBox/ValidationKit/testdriver/vbox.py          |    6 +-
 src/VBox/ValidationKit/testdriver/vboxtestvms.py   |   10 +-
 src/VBox/ValidationKit/testdriver/vboxwrappers.py  |   36 +-
 src/VBox/ValidationKit/testdriver/winbase.py       |    0
 src/VBox/ValidationKit/testmanager/__init__.py     |    0
 src/VBox/ValidationKit/testmanager/config.py       |    0
 .../ValidationKit/testmanager/core/__init__.py     |    0
 src/VBox/ValidationKit/testmanager/core/base.py    |    0
 src/VBox/ValidationKit/testmanager/core/build.py   |    0
 .../testmanager/core/buildblacklist.py             |    0
 .../ValidationKit/testmanager/core/buildsource.py  |    0
 .../ValidationKit/testmanager/core/coreconsts.py   |    0
 src/VBox/ValidationKit/testmanager/core/db.py      |    0
 .../ValidationKit/testmanager/core/dbobjcache.py   |    0
 .../testmanager/core/failurecategory.py            |    0
 .../testmanager/core/failurereason.py              |    0
 .../testmanager/core/globalresource.py             |    0
 src/VBox/ValidationKit/testmanager/core/report.py  |    0
 .../ValidationKit/testmanager/core/schedgroup.py   |    0
 .../testmanager/core/schedulerbase.py              |    0
 .../testmanager/core/schedulerbeci.py              |    0
 .../ValidationKit/testmanager/core/systemlog.py    |    0
 src/VBox/ValidationKit/testmanager/core/testbox.py |    0
 .../testmanager/core/testboxcontroller.py          |    0
 .../testmanager/core/testboxstatus.py              |    0
 .../ValidationKit/testmanager/core/testcase.py     |    0
 .../ValidationKit/testmanager/core/testcaseargs.py |    0
 .../ValidationKit/testmanager/core/testgroup.py    |    0
 .../ValidationKit/testmanager/core/testresults.py  |    0
 src/VBox/ValidationKit/testmanager/core/testset.py |    0
 .../ValidationKit/testmanager/core/useraccount.py  |    0
 .../ValidationKit/testmanager/core/vcsrevisions.py |    0
 .../testmanager/core/webservergluebase.py          |    0
 .../testmanager/core/webservergluecgi.py           |    0
 .../ValidationKit/testmanager/debug/__init__.py    |    0
 .../ValidationKit/testmanager/webui/__init__.py    |    0
 .../ValidationKit/testmanager/webui/wuiadmin.py    |    0
 .../testmanager/webui/wuiadminbuild.py             |    0
 .../testmanager/webui/wuiadminbuildblacklist.py    |    0
 .../testmanager/webui/wuiadminbuildcategory.py     |    0
 .../testmanager/webui/wuiadminbuildsource.py       |    0
 .../testmanager/webui/wuiadminfailurereason.py     |    0
 .../testmanager/webui/wuiadminglobalrsrc.py        |    0
 .../testmanager/webui/wuiadminschedgroup.py        |    0
 .../testmanager/webui/wuiadminsystemlog.py         |    0
 .../testmanager/webui/wuiadmintestbox.py           |    0
 .../testmanager/webui/wuiadmintestcase.py          |    0
 .../testmanager/webui/wuiadmintestgroup.py         |    0
 .../testmanager/webui/wuiadminuseraccount.py       |    0
 .../ValidationKit/testmanager/webui/wuibase.py     |    0
 .../testmanager/webui/wuicontentbase.py            |    0
 .../testmanager/webui/wuifailurecategory.py        |    0
 .../ValidationKit/testmanager/webui/wuigraphwiz.py |    0
 .../ValidationKit/testmanager/webui/wuihlpform.py  |    0
 .../testmanager/webui/wuihlpgraphgooglechart.py    |    0
 .../testmanager/webui/wuihlpgraphmatplotlib.py     |    0
 .../testmanager/webui/wuihlpgraphsimple.py         |    0
 .../testmanager/webui/wuilogviewer.py              |    0
 .../ValidationKit/testmanager/webui/wuimain.py     |    0
 .../ValidationKit/testmanager/webui/wuireport.py   |    0
 .../testmanager/webui/wuitestresult.py             |    0
 .../testmanager/webui/wuivcshistory.py             |    0
 .../tests/storage/tdStorageBenchmark1.py           |    4 +-
 .../tests/storage/tdStorageStress1.py              |    2 +-
 src/VBox/ValidationKit/utils/cpu/cidet-app.cpp     |    4 +
 src/libs/xpcom18a4/nsprpub/Makefile.in             |    0
 src/libs/xpcom18a4/nsprpub/config/config.mk        |    0
 src/libs/xpcom18a4/nsprpub/config/rules.mk         |    0
 src/libs/xpcom18a4/python/client/__init__.py       |    0
 src/libs/xpcom18a4/python/file.py                  |    0
 src/libs/xpcom18a4/python/primitives.py            |    0
 src/libs/xpcom18a4/python/server/__init__.py       |    0
 src/libs/xpcom18a4/python/server/enumerator.py     |    0
 src/libs/xpcom18a4/python/server/factory.py        |    0
 src/libs/xpcom18a4/python/server/loader.py         |    0
 src/libs/xpcom18a4/python/server/module.py         |    0
 src/libs/xpcom18a4/python/server/policy.py         |    0
 .../xpcom18a4/python/test/pyxpcom_test_tools.py    |    0
 .../xpcom18a4/python/test/test_com_exceptions.py   |    0
 src/libs/xpcom18a4/python/test/test_comfile.py     |    0
 .../test/test_component/py_test_component.py       |    0
 src/libs/xpcom18a4/python/test/test_components.py  |    0
 .../python/test/test_isupports_primitives.py       |    0
 src/libs/xpcom18a4/python/test/test_misc.py        |    0
 src/libs/xpcom18a4/python/test/test_streams.py     |    0
 .../xpcom18a4/python/test/test_test_component.py   |    0
 .../xpcom18a4/python/test/test_weakreferences.py   |    0
 src/libs/xpcom18a4/python/tools/regxpcom.py        |    0
 src/libs/xpcom18a4/python/xpt.py                   |    0
 748 files changed, 15180 insertions(+), 8386 deletions(-)

diff --git a/Config.kmk b/Config.kmk
index a18af20..bf6fba6 100644
--- a/Config.kmk
+++ b/Config.kmk
@@ -220,17 +220,17 @@ VBOX_BUILD_PUBLISHER =
 # Note! The BETA[n],ALPHA[n],RC[n] indicators should be inserted before the
 #       publisher so that RTStrVersionCompare have a chance of comparing
 #       prerelease from different publishers correctly.
-VBOX_VERSION_STRING = $(VBOX_VERSION_STRING_RAW)_BETA1$(VBOX_BUILD_PUBLISHER)
+VBOX_VERSION_STRING = $(VBOX_VERSION_STRING_RAW)_BETA2$(VBOX_BUILD_PUBLISHER)
 
 # Force the additions.sh script to get an exact additions build when we're doing the release.
 ifeq ($(int-mod $(VBOX_VERSION_BUILD),2),0)
   VBOX_RELEASE_EXACT_MATCH=1
 endif
 ifneq ($(VBOX_RELEASE_EXACT_MATCH),)
- export VBOX_ADDITIONS_SH_MODE     = release
- export VBOX_DOCUMENTATION_SH_MODE = release
- export VBOX_EFI_SH_MODE           = release
- export VBOX_EXTPACKS_SH_MODE      = release
+# export VBOX_ADDITIONS_SH_MODE     = release
+# export VBOX_DOCUMENTATION_SH_MODE = release
+# export VBOX_EFI_SH_MODE           = release
+# export VBOX_EXTPACKS_SH_MODE      = release
 endif
 
 # Some info on the vendor
@@ -726,7 +726,7 @@ endif
 # Set this to enable support for dtrace probes in guest code.
 #VBOX_WITH_DTRACE_GST = 1
 # Set this to indicate that the host ships with DTrace.
-if1of ($(KBUILD_TARGET), darwin solaris freebsd)
+if1of ($(KBUILD_TARGET), darwin solaris)
  VBOX_WITH_NATIVE_DTRACE = 1
 endif
 ## @}
@@ -3696,7 +3696,7 @@ TEMPLATE_VBOXR0DRV_CFLAGS              =  \
 	$(VBOX_GCC_WARN) -Wpointer-arith -Winline $(VBOX_GCC_Wno-pointer-sign) $(VBOX_GCC_fdiagnostics-show-option) \
 	-Wstrict-prototypes -Wmissing-prototypes -Wstrict-prototypes \
 	-Wimplicit-function-declaration -Werror-implicit-function-declaration \
-	-O2 -fformat-extensions -ffreestanding -fno-strict-aliasing -fno-common -finline-limit=8000 \
+	-O2 -ffreestanding -fno-strict-aliasing -fno-common -finline-limit=8000 \
 	$(VBOX_GCC_fno-stack-protector) $(VBOX_GCC_R0_OPT) $(VBOX_GCC_R0_FP) \
 	-nostdinc -std=c99
 TEMPLATE_VBOXR0DRV_CFLAGS.x86          = -m32 -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-3dnow -mno-sse -mno-sse2
@@ -3705,7 +3705,7 @@ TEMPLATE_VBOXR0DRV_CFLAGS.amd64        = -m64 --param inline-unit-growth=100 --p
 	-mno-3dnow -msoft-float -fno-asynchronous-unwind-tables -Wundef
 TEMPLATE_VBOXR0DRV_CXXFLAGS            = -fno-exceptions -fno-rtti \
 	$(VBOX_GCC_WARN) -Wpointer-arith -Winline \
-	-O2 -fno-format-extensions -fno-strict-aliasing -fno-common -finline-limit=8000 \
+	-O2 -fno-strict-aliasing -fno-common -finline-limit=8000 \
 	$(VBOX_GCC_fno-stack-protector) $(VBOX_GCC_R0_OPT) $(VBOX_GCC_R0_FP) \
 	-nostdinc
 TEMPLATE_VBOXR0DRV_CXXFLAGS.x86        = $(TEMPLATE_VBOXR0DRV_CFLAGS.x86)
@@ -3905,7 +3905,7 @@ TEMPLATE_VBOXR3EXE_LDFLAGS.x86         = -m32
 TEMPLATE_VBOXR3EXE_LDFLAGS.amd64       = -m64
 TEMPLATE_VBOXR3EXE_LDFLAGS.sparc32     = -m32
 TEMPLATE_VBOXR3EXE_LDFLAGS.sparc64     = -m64
-TEMPLATE_VBOXR3EXE_LDFLAGS.linux       = -Wl,-z,noexecstack $(VBOX_LD_as_needed)
+TEMPLATE_VBOXR3EXE_LDFLAGS.linux       = -Wl,-z,noexecstack,-z,relro $(VBOX_LD_as_needed)
 TEMPLATE_VBOXR3EXE_LDFLAGS.solaris     = -Wl,-z,ignore # same as VBOX_LD_as_needed
 
  ifeq ($(KBUILD_TARGET),linux)
@@ -4610,7 +4610,7 @@ TEMPLATE_VBOXMAINEXE_LDFLAGS.x86         = -m32
 TEMPLATE_VBOXMAINEXE_LDFLAGS.amd64       = -m64
  ifeq ($(KBUILD_TARGET),linux)
 TEMPLATE_VBOXMAINEXE_LIBS                = pthread m rt $(LIB_RUNTIME) dl
-TEMPLATE_VBOXMAINEXE_LDFLAGS.linux       = -Wl,-z,noexecstack $(VBOX_LD_as_needed)
+TEMPLATE_VBOXMAINEXE_LDFLAGS.linux       = -Wl,-z,noexecstack,-z,relro $(VBOX_LD_as_needed)
  else ifeq ($(KBUILD_TARGET),os2)
 TEMPLATE_VBOXMAINEXE_TOOL                = GXX3OMF
 TEMPLATE_VBOXMAINEXE_LIBS                = $(LIB_RUNTIME)
@@ -5072,7 +5072,7 @@ ifdef VBOX_WITH_QTGUI
 	$(VBOX_LIB_VMM_LAZY)
 
   ifeq ($(KBUILD_TARGET),linux)
-   TEMPLATE_VBOXQT4GUIEXE_LDFLAGS += -Wl,-z,noexecstack $(VBOX_LD_as_needed)
+   TEMPLATE_VBOXQT4GUIEXE_LDFLAGS += -Wl,-z,noexecstack,-z,relro $(VBOX_LD_as_needed)
    TEMPLATE_VBOXQT4GUIEXE_LIBS += \
      $(VBOX_XCURSOR_LIBS) \
 	Xext \
@@ -5955,7 +5955,7 @@ endif
 SVN                    ?= svn$(HOSTSUFF_EXE)
 VBOX_SVN_REV_KMK        = $(PATH_OUT)/revision.kmk
 ifndef VBOX_SVN_REV
- VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 99371 $  )
+ VBOX_SVN_REV_FALLBACK := $(patsubst %:,,  $Rev: 99573 $  )
  VBOX_SVN_DEP          := $(firstword $(wildcard $(PATH_ROOT)/.svn/wc.db $(abspath $(PATH_ROOT)/../.svn/wc.db) $(abspath $(PATH_ROOT)/../../.svn/wc.db) $(PATH_ROOT)/.svn/entries))
  ifeq ($(which $(SVN)),)
   VBOX_SVN_DEP         :=
diff --git a/configure.vbs b/configure.vbs
index ca047af..adf1cf4 100644
--- a/configure.vbs
+++ b/configure.vbs
@@ -1446,7 +1446,7 @@ sub CheckForMinGW32(strOptMinGW32, strOptW32API)
    ' Success?
    if strPathMingW32 = "" then
       if g_strTargetArch = "amd64" then
-         MsgWarning "Can't locate a suitable MinGW32 installation, ignoring since we're targetting AMD64 and won't need it."
+         MsgWarning "Can't locate a suitable MinGW32 installation, ignoring since we're targeting AMD64 and won't need it."
       elseif strOptMinGW32 = "" then
          MsgError "Can't locate a suitable MinGW32 installation. Try specify the path with " _
             & "the --with-MinGW32=<path> argument. If still no luck, consult the configure.log and the build requirements."
@@ -1583,7 +1583,7 @@ sub CheckForMinGWw64(strOptMinGWw64)
    ' Success?
    if strPathMinGWw64 = "" then
       if g_strTargetArch = "x86" then
-         MsgWarning "Can't locate a suitable MinGW-w64 installation, ignoring since we're targetting x86 and won't need it."
+         MsgWarning "Can't locate a suitable MinGW-w64 installation, ignoring since we're targeting x86 and won't need it."
       elseif strOptMinGWw64 = "" then
          MsgError "Can't locate a suitable MinGW-w64 installation. Try specify the path with " _
             & "the --with-MinGW-w64=<path> argument. If still no luck, consult the configure.log and the build requirements."
diff --git a/doc/manual/en_US/SDKRef.xml b/doc/manual/en_US/SDKRef.xml
index 1f51473..61e282d 100644
--- a/doc/manual/en_US/SDKRef.xml
+++ b/doc/manual/en_US/SDKRef.xml
@@ -141,7 +141,7 @@
           <listitem>
             <para>Internally, for portability and easier maintenance, the Main
             API is implemented using the <emphasis role="bold">Component
-            Object Model (COM),</emphasis> an interprocess mechanism for
+            Object Model (COM), </emphasis> an interprocess mechanism for
             software components originally introduced by Microsoft for
             Microsoft Windows. On a Windows host, VirtualBox will use
             Microsoft COM; on other hosts where COM is not present, it ships
@@ -1391,14 +1391,14 @@ string result = service.SayHello("Peter");  // invoke remote procedure</screen>a
 
             <orderedlist>
               <listitem>
-                <para>For <emphasis role="bold">C++,</emphasis> among many
+                <para>For <emphasis role="bold">C++, </emphasis> among many
                 others, the gSOAP toolkit is a good option. Parts of gSOAP are
                 also used in VirtualBox to implement the VirtualBox web
                 service.</para>
               </listitem>
 
               <listitem>
-                <para>For <emphasis role="bold">Java,</emphasis> there are
+                <para>For <emphasis role="bold">Java, </emphasis> there are
                 several implementations already described in this document
                 (see <xref linkend="glue-jax-ws" /> and <xref
                 linkend="webservice-java-sample" />).</para>
@@ -3497,7 +3497,7 @@ extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *pt
     Linux guests by dragging files, directories or text from the host into the
     guest's screen. This is called <emphasis>drag'n drop (DnD)</emphasis>.</para>
 
-    <para>In version 4.4 support for Windows guests has been added, as well as
+    <para>In version 5.0 support for Windows guests has been added, as well as
     the ability to transfer data the other way around, that is, from the guest
     to the host.</para>
 
@@ -3852,10 +3852,86 @@ AuthResult AUTHCALL AuthEntry(
     existing client code.</para>
 
     <sect1>
-      <title>Incompatible API changes with version 4.4</title>
+      <title>Incompatible API changes with version 5.0</title>
 
       <itemizedlist>
         <listitem>
+          <para>The methods for saving state, adopting a saved state file,
+          discarding a saved state, taking a snapshot, restoring
+          a snapshot and deleting a snapshot have been moved from
+          <computeroutput>IConsole</computeroutput> to
+          <computeroutput>IMachine</computeroutput>. This straightens out the
+          logical placement of methods and was necessary to resolve a
+          long-standing issue, preventing 32 bit API clients from invoking
+          those operations in the case where no VM is running.
+          <itemizedlist>
+            <listitem><xref linkend="IMachine__saveState"
+                xreflabel="IMachine::saveState()" /> replaces
+              <computeroutput>IConsole::saveState()</computeroutput>
+            </listitem>
+            <listitem>
+              <xref linkend="IMachine__adoptSavedState"
+                xreflabel="IMachine::adoptSavedState()" /> replaces
+              <computeroutput>IConsole::adoptSavedState()</computeroutput>
+            </listitem>
+            <listitem>
+              <xref linkend="IMachine__discardSavedState"
+                xreflabel="IMachine::discardSavedState()" /> replaces
+              <computeroutput>IConsole::discardSavedState()</computeroutput>
+            </listitem>
+            <listitem>
+              <xref linkend="IMachine__takeSnapshot"
+                xreflabel="IMachine::takeSnapshot()" /> replaces
+              <computeroutput>IConsole::takeSnapshot()</computeroutput>
+            </listitem>
+            <listitem>
+              <xref linkend="IMachine__deleteSnapshot"
+                xreflabel="IMachine::deleteSnapshot()" /> replaces
+              <computeroutput>IConsole::deleteSnapshot()</computeroutput>
+            </listitem>
+            <listitem>
+              <xref linkend="IMachine__deleteSnapshotAndAllChildren"
+                xreflabel="IMachine::deleteSnapshotAndAllChildren()" /> replaces
+              <computeroutput>IConsole::deleteSnapshotAndAllChildren()</computeroutput>
+            </listitem>
+            <listitem>
+               <xref linkend="IMachine__deleteSnapshotRange"
+                xreflabel="IMachine::deleteSnapshotRange()" /> replaces
+               <computeroutput>IConsole::deleteSnapshotRange()</computeroutput>
+             </listitem>
+             <listitem>
+               <xref linkend="IMachine__restoreSnapshot"
+                xreflabel="IMachine::restoreSnapshot()" /> replaces
+               <computeroutput>IConsole::restoreSnapshot()</computeroutput>
+             </listitem>
+           </itemizedlist>
+          Small adjustments to the parameter lists have been made to reduce
+          the number of API calls when taking online snapshots etc.</para>
+        </listitem>
+
+        <listitem>
+          <para>Two new machine states have been introduced to allow proper
+          distinction between saving state and taking a snapshot.
+          <xref linkend="MachineState__Saving" xreflabel="MachineState::Saving" />
+          now is used exclusively while the VM's state is being saved, without
+          any overlaps with snapshot functionality. The new state
+          <xref linkend="MachineState__Snapshotting" xreflabel="MachineState::Snapshotting" />
+          is used when an offline snapshot is taken and likewise the new state
+          <xref linkend="MachineState__OnlineSnapshotting" xreflabel="MachineState::OnlineSnapshotting" />
+          is used when an online snapshot is taken.</para>
+        </listitem>
+
+        <listitem>
+          <para>A new event has been introduced, which signals when a snapshot has been
+          restored:
+          <xref linkend="ISnapshotRestoredEvent" xreflabel="ISnapshotRestoredEvent"/>.
+          Previously the event
+          <xref linkend="ISnapshotDeletedEvent" xreflabel="ISnapshotDeletedEvent"/> was
+          signalled, which isn't logical (but could be distinguished from actual deletion
+          by the fact that the snapshot was still there).</para>
+        </listitem>
+
+        <listitem>
           <para>The method <xref linkend="IVirtualBox__createMedium"
           xreflabel="IVirtualBox::createMedium()" /> replaces
           <computeroutput>VirtualBox::createHardDisk()</computeroutput>.
@@ -4702,9 +4778,7 @@ AuthResult AUTHCALL AuthEntry(
 
               <listitem>
                 <para><computeroutput>IConsole::forgetSavedState</computeroutput>
-                has been renamed to <xref
-                linkend="IConsole__discardSavedState"
-                xreflabel="IConsole::discardSavedState()" />.</para>
+                has been renamed to <computeroutput>IConsole::discardSavedState()</computeroutput>.</para>
               </listitem>
             </itemizedlist></para>
         </listitem>
@@ -4965,12 +5039,12 @@ AuthResult AUTHCALL AuthEntry(
         </listitem>
 
         <listitem>
-          <para>Deleting snapshots via <xref
-          linkend="IConsole__deleteSnapshot"
-          xreflabel="IConsole::deleteSnapshot()" /> is now possible while the
-          associated VM is running in almost all cases. The API is unchanged,
-          but client code that verifies machine states to determine whether
-          snapshots can be deleted may need to be adjusted.</para>
+          <para>Deleting snapshots via
+          <computeroutput>IConsole::deleteSnapshot()</computeroutput> is now
+          possible while the associated VM is running in almost all cases.
+          The API is unchanged, but client code that verifies machine states
+          to determine whether snapshots can be deleted may need to be
+          adjusted.</para>
         </listitem>
 
         <listitem>
@@ -5080,18 +5154,15 @@ AuthResult AUTHCALL AuthEntry(
         <listitem>
           <para>There were substantial changes related to snapshots, triggered
           by the "branched snapshots" functionality introduced with version
-          3.1. IConsole::discardSnapshot was renamed to <xref
-          linkend="IConsole__deleteSnapshot"
-          xreflabel="IConsole::deleteSnapshot()" />.
+          3.1. IConsole::discardSnapshot was renamed to
+          <computeroutput>IConsole::deleteSnapshot()</computeroutput>.
           IConsole::discardCurrentState and
           IConsole::discardCurrentSnapshotAndState were removed; corresponding
-          new functionality is in <xref linkend="IConsole__restoreSnapshot"
-          xreflabel="IConsole::restoreSnapshot()" />. Also, when <xref
-          linkend="IConsole__takeSnapshot"
-          xreflabel="IConsole::takeSnapshot()" /> is called on a running
-          virtual machine, a live snapshot will be created. The old behavior
-          was to temporarily pause the virtual machine while creating an
-          online snapshot.</para>
+          new functionality is in <computeroutput>IConsole::restoreSnapshot()</computeroutput>.
+          Also, when <computeroutput>IConsole::takeSnapshot()</computeroutput>
+          is called on a running virtual machine, a live snapshot will be
+          created. The old behavior was to temporarily pause the virtual
+          machine while creating an online snapshot.</para>
         </listitem>
 
         <listitem>
diff --git a/doc/manual/en_US/user_AdvancedTopics.xml b/doc/manual/en_US/user_AdvancedTopics.xml
index facf590..01de728 100644
--- a/doc/manual/en_US/user_AdvancedTopics.xml
+++ b/doc/manual/en_US/user_AdvancedTopics.xml
@@ -1790,18 +1790,18 @@ VBoxManage setextradata "VM name"
       </footnote> A VirtualBox VNIC template is a VNIC whose name starts with
     "vboxvnic_template" (case-sensitive).</para>
  
-    <para>On Solaris 11 hosts (i.e. when the default Crossbow based bridged
-    networking is used), using a VNIC template is the only means of specifying
-    a VLAN ID to use while bridging over a link.</para>
+    <para>On Solaris 11 hosts<footnote><para>When Crossbow based bridged
+    networking is used.</para></footnote>, a VNIC template may be used to
+    specify the VLAN ID to use while bridging over a network link.</para>
 
-    <para>Here is an example of how to use a VNIC template to configure a VLAN
-    for VMs. Create a VirtualBox VNIC template, by executing as root:</para>
+    <para>Here is an example of how to use a VNIC template to configure a VM
+    over a VLAN. Create a VirtualBox VNIC template, by executing as root:</para>
 
     <screen>dladm create-vnic -t -l nge0 -v 23 vboxvnic_template0</screen>
 
-    <para>This will create a temporary VNIC over interface "nge0" with the
-    VLAN ID 23. To create VNIC templates that are persistent across host
-    reboots, skip the <computeroutput>-t</computeroutput> parameter in the
+    <para>This will create a temporary VNIC template over interface "nge0"
+    with the VLAN ID 23. To create VNIC templates that are persistent across
+    host reboots, skip the <computeroutput>-t</computeroutput> parameter in the
     above command. You may check the current state of links using:</para>
 
     <para><screen>$ dladm show-link
@@ -1814,20 +1814,19 @@ $ dladm show-vnic
 LINK         OVER         SPEED  MACADDRESS        MACADDRTYPE         VID
 vboxvnic_template0 nge0   1000   2:8:20:25:12:75   random              23</screen></para>
 
-    <para>In the example above, once the VNIC template is created, any VMs
-    that need to be on VLAN 23 over the physical interface "nge0" can use
-    the VNIC template.</para>
+    <para>Once the VNIC template is created, any VMs that need to be on VLAN
+    23 over the interface "nge0" can be configured to bridge using this VNIC
+    template.</para>
 
-    <para>VNIC templates makes managing VMs on VLANs simpler and efficient, as
-    the VLAN details are not stored as part of every VM's configuration but
-    rather inherited from the VNIC template which can be modified anytime
-    using <computeroutput>dladm</computeroutput>.</para>
+    <para>VNIC templates makes managing VMs on VLANs simpler and efficient.
+    The VLAN details are not stored as part of every VM's configuration but
+    rather inherited from the VNIC template while starting the VM. The VNIC
+    template itself can be modified anytime using <computeroutput>dladm</computeroutput>.</para>
 
-    <para>Apart from the VLAN ID, VNIC templates can be created with
-    additional properties such as bandwidth limits, CPU fanout etc. Refer to
-    your Solaris network documentation on how to accomplish this.
-    These additional properties, if any, are also applied to VMs which use
-    the VNIC template.</para>
+    <para>VNIC templates can be created with additional properties such as
+    bandwidth limits, CPU fanout etc. Refer to your Solaris network
+    documentation on how to accomplish this. These additional properties,
+    if any, are also applied to VMs which bridge using the VNIC template.</para>
   </sect1>
 
   <sect1 id="addhostonlysolaris">
@@ -1943,6 +1942,31 @@ VBoxManage setextradata "VM name" VBoxInternal2/CoreDumpLive 1</screen>At
     for example <computeroutput>core.vb.VBoxHeadless.11321</computeroutput>.</para>
   </sect1>
 
+  <sect1 id="vboxandsolzvmm">
+    <title>VirtualBox and Solaris kernel zones</title>
+
+    <para>Solaris kernel zones on x86-based systems make use of hardware-assisted
+    virtualization features like VirtualBox does. However, for kernel zones and
+    VirtualBox to share this hardware resource, they need to co-operate.</para>
+
+    <para>By default, due to performance reasons, VirtualBox acquires the
+    hardware-assisted virtualization resource (VT-x/AMD-V) globally on the
+    host machine and uses it until the last VirtualBox VM that requires it is
+    powered off. This prevents other software from using VT-x/AMD-V during the
+    time VirtualBox has taken control of it.</para>
+
+    <para>VirtualBox can be instructed to relinquish use of hardware-assisted
+    virtualization features when not executing guest code, thereby allowing
+    kernel zones to make use of them. To do this, shutdown all VirtualBox VMs
+    and execute the following command:</para>
+
+    <screen>VBoxManage setproperty hwvirtexclusive off</screen>
+
+    <para>This command needs to be executed only once as the setting is stored
+    as part of the global VirtualBox settings which will continue to persist
+    across host-reboots and VirtualBox upgrades.</para>
+  </sect1>
+
   <sect1 id="guitweaks">
     <title>Locking down the VirtualBox manager GUI</title>
 
@@ -3606,7 +3630,7 @@ VBoxManage setextradata "foo" "VBoxInternal2/SavestateOnBatteryLow" 0</screen>
      </para>
 
    </sect1>
-   
+
    <sect1 id="sse412passthrough">
      <title>Experimental support for passing through SSE4.1 / SSE4.2 instructions</title>
      <para>
@@ -3639,4 +3663,31 @@ VBoxManage setextradata "VM name" VBoxInternal/CPUM/SSE4.2 1</screen>
 
   </sect1>
 
+  <sect1 id="usbtrafficcapturing">
+    <title>Capturing USB traffic for selected devices</title>
+
+    <para>
+      Starting with VirtualBox 5.0 it is possible to capture USB traffic for
+      single USB devices or on the root hub level which captures the traffic of
+      all USB devices attached to the root hub. VirtualBox stores the traffic
+      in a format which is compatible with Wireshark. To capture the traffic
+      of a specific USB device it must be attached to the VM with VBoxManage
+      using the following command:
+    </para>
+
+    <screen>VBoxManage controlvm "VM name" usbattach "device uuid|address" --capturefile "filename"</screen>
+
+    <para>
+      In order to enable capturing on the root hub use the following command
+      while the VM is not running:
+    </para>
+
+    <screen>VBoxManage setextradata "VM name" VBoxInternal/Devices/usb-ehci/LUN#0/Config/CaptureFilename "filename"</screen>
+
+    The command above enables capturing on the root hub attached to the EHCI controller.
+    To enable it for the OHCI or XHCI controller replace <computeroutput>usb-ehci</computeroutput>
+    with <computeroutput>usb-ohci</computeroutput> or <computeroutput>usb-xhci</computeroutput> respectively.
+
+  </sect1>
+
 </chapter>
diff --git a/doc/manual/en_US/user_BasicConcepts.xml b/doc/manual/en_US/user_BasicConcepts.xml
index 3bedd6c..2ae956f 100644
--- a/doc/manual/en_US/user_BasicConcepts.xml
+++ b/doc/manual/en_US/user_BasicConcepts.xml
@@ -707,6 +707,14 @@
       VT-x) features, then you can expect a significant performance increase
       by enabling nested paging in addition to hardware virtualization. For
       technical details, see <xref linkend="nestedpaging" />.</para>
+      
+      <para>Starting with version 5.0, VirtualBox provides paravirtualization
+      interfaces to improve time-keeping accuracy and performance of guest
+      operating systems. The options available are documented under the
+      <computeroutput>paravirtprovider</computeroutput> option
+      in <xref linkend="vboxmanage-modifyvm" />. For futher details on
+      the paravirtualization providers, please refer to
+      <xref linkend="gimproviders" />.</para>
     </sect2>
   </sect1>
 
@@ -1129,16 +1137,6 @@
                       where <computeroutput><name></computeroutput> should
                       identify the virtual machine but may be freely
                       chosen.</para>
-                      <para>For forwarding serial traffic, you can use a helper
-                      program called VMware Serial Line Gateway, available for
-                      download at
-                                  <literal> <ulink
-                      url="http://www.l4ka.org/91.php">http://www.l4ka.org/91.php</ulink>
-                      </literal>. This tool provides a fixed server mode named
-                      pipe at
-                      <computeroutput>\\.\pipe\vmwaredebug</computeroutput>
-                      and connects incoming TCP connections on port 567 with
-                      the named pipe.</para>
                     </listitem>
 
                     <listitem>
@@ -1178,6 +1176,27 @@
                 write to the file.
                 </para>
               </listitem>
+
+              <listitem>
+                <para>TCP Socket: useful for forwarding serial traffic over TCP/IP, acting as a server,
+                   or it can act as a TCP client connecting to other servers.
+                   It allows remote machine to connect via TCP directly to guest's serial port.
+                </para>
+                <para>TCP Server: use "create socket" mode, and type in only the <emphasis role="bold">
+                  <computeroutput>port</computeroutput></emphasis> number.
+                   Typically 23 or 2023. Note that on UNIX-like systems you will have to use port
+                   number over 1024 for normal users.
+                </para>
+                <para>
+                   The client can use software such as "Putty" or command-line "telnet" to access TCP Server.
+                </para>
+                <para>TCP Client: to create a virtual null-modem cable over the Internet or LAN,
+                   the other side can connect via TCP by specifying <emphasis role="bold">
+                   <computeroutput>hostname:port</computeroutput></emphasis>.
+                   TCP socket will act in client mode, if you remove "create socket" mode.
+                </para>
+              </listitem>
+
             </itemizedlist></para>
         </listitem>
       </orderedlist>Up to two serial ports can be configured per virtual
diff --git a/doc/manual/en_US/user_GuestAdditions.xml b/doc/manual/en_US/user_GuestAdditions.xml
index 16ef70e..61853a9 100644
--- a/doc/manual/en_US/user_GuestAdditions.xml
+++ b/doc/manual/en_US/user_GuestAdditions.xml
@@ -1250,7 +1250,7 @@ $</screen>
   <sect1 id="guestadd-dnd">
     <title>Drag'n Drop</title>
 
-    <para>Starting with version 4.4, VirtualBox supports to drag'n drop content
+    <para>Starting with version 5.0, VirtualBox supports to drag'n drop content
     from the host to the guest and vice versa. For this to work the latest Guest
     Additions must be installed on the guest.</para>
 
diff --git a/doc/manual/en_US/user_Introduction.xml b/doc/manual/en_US/user_Introduction.xml
index 634a8fc..78284b1 100644
--- a/doc/manual/en_US/user_Introduction.xml
+++ b/doc/manual/en_US/user_Introduction.xml
@@ -441,7 +441,7 @@
             <para>Preliminary Mac OS X support (beta stage) was added with
             VirtualBox 1.4, full support with 1.6. Mac OS X 10.4 (Tiger)
             support was removed with VirtualBox 3.1. Mac OS X 10.7 (Lion)
-            and earlier was removed with VirtualBox 4.4</para>
+            and earlier was removed with VirtualBox 5.0.</para>
           </footnote></para>
 
         <itemizedlist>
diff --git a/doc/manual/en_US/user_Storage.xml b/doc/manual/en_US/user_Storage.xml
index ee9cd6c..f339366 100644
--- a/doc/manual/en_US/user_Storage.xml
+++ b/doc/manual/en_US/user_Storage.xml
@@ -35,30 +35,31 @@
   section.</para>
 
   <sect1 id="harddiskcontrollers">
-    <title>Hard disk controllers: IDE, SATA (AHCI), SCSI, SAS</title>
+    <title>Hard disk controllers: IDE, SATA (AHCI), SCSI, SAS, USB MSC</title>
 
     <para>In a real PC, hard disks and CD/DVD drives are connected to a device
     called hard disk controller which drives hard disk operation and data
-    transfers. VirtualBox can emulate the four most common types of hard disk
-    controllers typically found in today's PCs: IDE, SATA (AHCI), SCSI and
-    SAS.<footnote>
+    transfers. VirtualBox can emulate the five most common types of hard disk
+    controllers typically found in today's PCs: IDE, SATA (AHCI), SCSI,
+    SAS and USB-based mass storage devices.<footnote>
         <para>SATA support was added with VirtualBox 1.6; experimental SCSI
         support was added with 2.1 and fully implemented with 2.2. Generally,
         storage attachments were made much more flexible with VirtualBox 3.1;
         see below. Support for the LSI Logic SAS controller was added with
-        VirtualBox 3.2.</para>
+        VirtualBox 3.2; USB mass storage devices are supported since
+        VirtualBox 5.0.</para>
       </footnote><itemizedlist>
         <listitem>
           <para><emphasis role="bold">IDE (ATA)</emphasis> controllers are a
           backwards compatible yet very advanced extension of the disk
-	  controller in the IBM PC/AT (1984). Initially, this interface
+          controller in the IBM PC/AT (1984). Initially, this interface
           worked only with hard disks, but was later extended to also support
           CD-ROM drives and other types of removable media. In physical PCs,
           this standard uses flat ribbon parallel cables with 40 or 80 wires.
           Each such cable can connect two devices to a controller, which have
           traditionally been called "master" and "slave". Typical PCs had
           two connectors for such cables; as a result, support for up to four
-	  IDE devices was most common.</para>
+          IDE devices was most common.</para>
 
           <para>In VirtualBox, each virtual machine may have one IDE
           contoller enabled, which gives you up to four virtual storage
@@ -189,6 +190,25 @@
             see such disks unless you install additional drivers.</para>
           </warning>
         </listitem>
+
+        <listitem>
+          <para>The <emphasis role="bold">USB mass storage device class</emphasis>
+          is a standard to connect external storage devices like hard disksor flash
+          drives to a host through USB. All major operating systems support these
+          devices for a long time and ship generic drivers making third-party
+          drivers superfluous. In particular legacy operating systems without
+          support for SATA controllers may benefit from USB mass storage devices.</para>
+          <para>The virtual USB storage controller offered by VirtualBox works
+          different than the other storage controller types: When storage
+          controllers appear as a single PCI device to the guest with multiple
+          disks attached to it, the USB-based storage controller does not appear
+          as virtual storage controller. Each disk attached to the controller
+          appears as a dedicated USB device to the guest.</para>
+          <warning>
+            <para>Booting from drives attached via USB is not supported as the
+              BIOS lacks USB support.</para>
+          </warning>
+        </listitem>
       </itemizedlist></para>
 
     <para>In summary, VirtualBox gives you the following categories of virtual
@@ -213,6 +233,11 @@
           <para>eight slots attached to the SAS controller, if enabled and
           supported by the guest operating system.</para>
         </listitem>
+
+        <listitem>
+          <para>eight slots attached to the virtual USB controller, if enabled and
+          supported by the guest operating system.</para>
+        </listitem>
       </orderedlist></para>
 
     <para>Given this large choice of storage controllers, you may ask yourself
diff --git a/doc/manual/en_US/user_Technical.xml b/doc/manual/en_US/user_Technical.xml
index 713d80a..674ffb3 100644
--- a/doc/manual/en_US/user_Technical.xml
+++ b/doc/manual/en_US/user_Technical.xml
@@ -585,6 +585,49 @@
     </warning>
   </sect1>
 
+  <sect1 id="gimproviders">
+    <title>Paravirtualization providers</title>
+
+    <para>VirtualBox allows exposing a paravirtualization interface to
+    facilitate accurate and efficient execution of software within a
+    virtual machine. These interfaces require the guest operating system
+    to recognize their presence and make use of them in order to leverage
+    the benefits of communicating with the VirtualBox hypervisor.</para>
+    
+    <para>Most mainstream, modern operating systems, including Windows and
+    Linux, ship with support for one or more paravirtualization interfaces.
+    Hence, there is typically no need to install additional software in the
+    guest (including VirtualBox Guest Additions) to make use of this
+    feature.</para>
+
+    <para>VirtualBox provides the following interfaces:</para>
+      <itemizedlist>
+        <listitem>
+          <para><emphasis role="bold">Minimal</emphasis>: Announces the
+          presence of a virtualized environment, additionally reports the
+          TSC and APIC frequency to the guest operating system. This provider
+          is mandatory for running any Mac OS X guests.</para>
+        </listitem>
+
+        <listitem>
+          <para><emphasis role="bold">KVM</emphasis>: Presents a Linux KVM
+          hypervisor interface which is recognized by Linux kernels starting
+          with version 2.6.25. VirtualBox's implementation currently supports
+          paravirtualized clocks and SMP spinlocks. This provider is
+          recommended for Linux guests.</para>
+        </listitem>
+
+        <listitem>
+          <para><emphasis role="bold">Hyper-V</emphasis>: Presents a Microsoft
+          Hyper-V hypervisor interface which is recognized by Windows 7 and newer
+          operating systems. VirtualBox's implementation currently supports
+          paravirtualized clocks, APIC frequency reporting and relaxed timer
+          checks. This provider is recommended for Windows and FreeBSD guests.
+          </para>
+        </listitem>
+     </itemizedlist>
+  </sect1>
+
   <sect1>
     <title>Details about software virtualization</title>
 
@@ -701,8 +744,8 @@
         <listitem>
           <para>There are certain flaws in the implementation of ring 1 in the
           x86 architecture that were never fixed. Certain instructions that
-          <emphasis>should</emphasis> trap in ring 1 don't. This affect for
-          example the LGDT/SGDT, LIDT/SIDT, or POPF/PUSHF instruction pairs.
+          <emphasis>should</emphasis> trap in ring 1 don't. This affects, for
+          example, the LGDT/SGDT, LIDT/SIDT, or POPF/PUSHF instruction pairs.
           Whereas the "load" operation is privileged and can therefore be
           trapped, the "store" instruction always succeed. If the guest is
           allowed to execute these, it will see the true state of the CPU, not
diff --git a/doc/manual/en_US/user_VBoxManage.xml b/doc/manual/en_US/user_VBoxManage.xml
index 088f34a..3f5e96a 100644
--- a/doc/manual/en_US/user_VBoxManage.xml
+++ b/doc/manual/en_US/user_VBoxManage.xml
@@ -603,6 +603,27 @@ Statistics update:  disabled</screen></para>
           </listitem>
 
           <listitem>
+            <para><computeroutput>--paravirtprovider
+            none|default|legacy|minimal|hyperv|kvm</computeroutput>: This
+            setting specifies which paravirtualization interface to provide to
+            the guest operating system. Specifying
+            <computeroutput>none</computeroutput> explicitly turns off exposing
+            any paravirtualization interface. The option
+            <computeroutput>default</computeroutput>, will pick an appropriate
+            interface depending on the guest OS type while starting the VM.
+            This is the default option chosen while creating new VMs. The
+            <computeroutput>legacy</computeroutput> option is chosen for VMs
+            which were created with older VirtualBox versions and will pick a
+            paravirtualization interface while starting the VM with VirtualBox
+            5.0 and newer. The <computeroutput>minimal</computeroutput> provider
+            is mandatory for Mac OS X guests, while
+            <computeroutput>kvm</computeroutput> and
+            <computeroutput>hyperv</computeroutput> are recommended for Linux
+            and Windows guests respectively. These options are explained in
+            detail under <xref linkend="gimproviders" />.</para>
+          </listitem>
+
+          <listitem>
             <para><computeroutput>--nestedpaging on|off</computeroutput>: If
             hardware virtualization is enabled, this additional setting
             enables or disables the use of the nested paging feature in the
@@ -712,9 +733,10 @@ Statistics update:  disabled</screen></para>
             <size></computeroutput> sets the default size of the guest
             memory balloon, that is, memory allocated by the VirtualBox Guest
             Additions from the guest operating system and returned to the
-            hypervisor for re-use by other virtual machines. <size> must
-            be specified in megabytes. The default size is 0 megabytes. For
-            details, see <xref linkend="guestadd-balloon" />.</para>
+            hypervisor for re-use by other virtual machines.
+            <computeroutput><size></computeroutput> must be specified in
+            megabytes. The default size is 0 megabytes. For details,
+            see <xref linkend="guestadd-balloon" />.</para>
           </listitem>
 
           <listitem>
@@ -1001,6 +1023,23 @@ Statistics update:  disabled</screen></para>
                 </listitem>
 
                 <listitem>
+                  <para><computeroutput>tcpserver
+                  <port></computeroutput>: This
+                  tells VirtualBox to create a TCP socket on the host with TCP
+                  <computeroutput><port></computeroutput> and
+                  connect the virtual serial device to it. Note that UNIX-like
+                  systems require ports over 1024 for normal users.</para>
+                </listitem>
+
+                <listitem>
+                  <para><computeroutput>tcpclient
+                  <hostname:port></computeroutput>: This operates just like
+                  <computeroutput>tcpserver ...</computeroutput>, except that the
+                  TCP socket is not created by VirtualBox,
+                  but assumed to exist already.</para>
+                </listitem>
+                
+                <listitem>
                   <para><computeroutput><devicename></computeroutput>:
                   If, instead of the above, the device name of a physical
                   hardware serial port of the host is specified, the virtual
@@ -1448,6 +1487,17 @@ Virtual system 0:
           <para>Starts a VM with a minimal GUI and limited features.</para>
         </glossdef>
       </glossentry>
+
+      <glossentry>
+        <glossterm><computeroutput>separate</computeroutput></glossterm>
+
+        <glossdef>
+          <para>Starts a VM with detachable UI (technically it is a headless VM
+            with user interface in a separate process). This is an experimental
+            feature as it lacks certain functionality at the moment (e.g. 3D
+            acceleration will not work).</para>
+        </glossdef>
+      </glossentry>
     </glosslist>
 
     <note>
@@ -2152,7 +2202,7 @@ Virtual system 0:
                             --name <name>
                             [--add <ide/sata/scsi/floppy>]
                             [--controller <LsiLogic|LSILogicSAS|BusLogic|
-                                          IntelAhci|PIIX3|PIIX4|ICH6|I82078>]
+                                          IntelAhci|PIIX3|PIIX4|ICH6|I82078|usb>]
                             [--sataportcount <1-30>]
                             [--hostiocache on|off]
                             [--bootable on|off]
diff --git a/doc/manual/user_ChangeLogImpl.xml b/doc/manual/user_ChangeLogImpl.xml
index 90a3c4a..21f8612 100644
--- a/doc/manual/user_ChangeLogImpl.xml
+++ b/doc/manual/user_ChangeLogImpl.xml
@@ -9,11 +9,51 @@
     <itemizedlist>
 
       <listitem>
-        <para>Drag'n drop support (bidirectional) for Windows, Linux and Solaris guests</para>
+        <para>Paravirtualization support for Windows and Linux guests to improve
+          time-keeping accuracy and performance (see  <xref linkend="gimproviders" />)</para>
       </listitem>
 
       <listitem>
-        <para>GUI: Support hotplugging for SATA disks</para>
+        <para>Make more instruction set extensions available to the guest when
+          running with hardware-assisted virtualization and nested paging. Among
+          others this includes: SSE 4.1, SSE4.2, AES-NI, <emphasis>POPCNT</emphasis>,
+          <emphasis>RDRAND</emphasis> and <emphasis>RDSEED</emphasis></para>
+      </listitem>
+
+      <listitem>
+        <para>xHCI Controller to support USB 3 devices
+          (see <xref linkend="settings-usb" />)</para>
+      </listitem>
+
+      <listitem>
+        <para>Drag and drop support (bidirectional) for Windows, Linux and Solaris guests</para>
+      </listitem>
+
+      <listitem>
+        <para>Disk image encryption (see </para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: VM guest-content scaling support (including 3D acceleration)</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: New User Interface settings page for customizing status-bar,
+          menu-bar and guest-content scaling</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: New Encryption settings tab for customizing encryption options for
+          disk images</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: HiDPI support including application icons and optional unscaled HiDPI
+          output on Mac OS X (including 3D acceleration)</para>
+      </listitem>
+
+      <listitem>
+        <para>GUI: Hotplugging support for SATA disks</para>
       </listitem>
 
       <listitem>
@@ -21,6 +61,11 @@
           audio backends</para>
       </listitem>
 
+      <listitem>
+        <para>Support for the NDIS6 networking framework on Windows (default on Vista
+          and later)</para>
+      </listitem>
+
     </itemizedlist>
 
     <para>In addition, the following items were fixed and/or added:</para>
@@ -28,27 +73,40 @@
     <itemizedlist>
 
       <listitem>
+        <para>GUI: improved HID LEDs synchronization for Mac and Windows hosts.
+          Phisical LEDs state now restored together with VM state restore.</para>
+      </listitem>
+
+      <listitem>
         <para>VMM: improved timing on Solaris hosts with older VT-x hosts
           without preemption timers</para>
       </listitem>
 
       <listitem>
         <para>VBoxManage: when exporting an appliance, support the suppression
-           of MAC addresses, which means they will be always recreated on
-           import, avoiding duplicate MAC addresses for VMs which are imported
-           several times</para>
+          of MAC addresses, which means they will be always recreated on
+          import, avoiding duplicate MAC addresses for VMs which are imported
+          several times</para>
+      </listitem>
+
+      <listitem>
+        <para>USB: added USB traffic capturing (see <xref linkend="usbtrafficcapturing" />)</para>
+      </listitem>
+
+      <listitem>
+        <para>Made resizing X11 guests work more reliably</para>
       </listitem>
 
       <listitem>
         <para>API: block the removal of the current snapshot if it has child
-           snapshots (only relevant for VMs without snapshottable hard disks,
-           their presence always prevented removal), which resulted in VM
-           config corruption</para>
+          snapshots (only relevant for VMs without snapshottable hard disks,
+          their presence always prevented removal), which resulted in VM
+          config corruption</para>
       </listitem>
 
       <listitem>
         <para>API: mark VM configs with snapshots but without current snapshot
-           as inaccessible, as this combination is nonsense</para>
+          as inaccessible, as this combination is nonsense</para>
       </listitem>
 
       <listitem>
@@ -68,6 +126,15 @@
           be changed when the VM is in saved state</para>
       </listitem>
 
+      <listitem>
+        <para>3D: fix potential race in which might cause a crash on VM
+          termination</para>
+      </listitem>
+
+      <listitem>
+        <para>3D: fixed a possible memory leak in the host service</para>
+      </listitem>
+
     </itemizedlist>
 
   </sect1>
@@ -2894,7 +2961,7 @@
 
       <listitem>
         <para>X11 Additions: reduced the CPU load of VBoxClient in
-          drag'and'drop mode</para>
+          drag and drop mode</para>
       </listitem>
 
       <listitem>
@@ -3590,7 +3657,7 @@
       </listitem>
 
       <listitem>
-        <para>GUI: added menu for runtime drag-and-drop option change</para>
+        <para>GUI: added menu for runtime drag and drop option change</para>
       </listitem>
 
       <listitem>
@@ -3773,7 +3840,7 @@
       </listitem>
 
       <listitem>
-        <para>Added experimental support for drag'n'drop from the host to
+        <para>Added experimental support for drag and drop from the host to
           Linux guests. Support for more guests and for guest-to-host is
           planned. (bug #81)</para>
       </listitem>
diff --git a/include/VBox/HostServices/DragAndDropSvc.h b/include/VBox/HostServices/DragAndDropSvc.h
index e21ea66..784ad9b 100644
--- a/include/VBox/HostServices/DragAndDropSvc.h
+++ b/include/VBox/HostServices/DragAndDropSvc.h
@@ -69,7 +69,7 @@
     "STRING",                                                                                   \
     /* OpenOffice formats. */                                                                   \
     /* See: https://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/Common_Application_Features#OpenOffice.org_Clipboard_Data_Formats */ \
-    "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\""  \
+    "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"", \
     "application/x-openoffice;windows_formatname=\"Bitmap\""
 
 namespace DragAndDropSvc {
diff --git a/include/VBox/apic.h b/include/VBox/apic.h
index 3776238..6f0bca5 100644
--- a/include/VBox/apic.h
+++ b/include/VBox/apic.h
@@ -44,7 +44,7 @@
 #define APIC_REG_EILVT0                         0x0500
 #define APIC_REG_EILVT1                         0x0510
 #define APIC_REG_EILVT2                         0x0520
-#define APIC_REG_ELLVT3                         0x0530
+#define APIC_REG_EILVT3                         0x0530
 #define APIC_REG_LVT_MODE_MASK                  (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
 #define APIC_REG_LVT_MODE_FIXED                 0
 #define APIC_REG_LVT_MODE_NMI                   RT_BIT(10)
diff --git a/include/VBox/disopcode.h b/include/VBox/disopcode.h
index f5f11f4..3494d8f 100644
--- a/include/VBox/disopcode.h
+++ b/include/VBox/disopcode.h
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -741,10 +741,21 @@ enum OPCODES
     OP_INVEPT,
     OP_INVVPID,
     OP_INVPCID,
+    OP_VMFUNC,
+/** @}  */
+/** @name AMD-V instructions
+ * @{ */
+    OP_VMMCALL,
+    OP_VMRUN,
+    OP_VMLOAD,
+    OP_VMSAVE,
+    OP_CLGI,
+    OP_STGI,
+    OP_INVLPGA,
+    OP_SKINIT,
 /** @}  */
 /** @name 64 bits instruction
  * @{ */
-
     OP_MOVSXD
 /** @} */
 };
diff --git a/include/VBox/err.h b/include/VBox/err.h
index 76ffb16..156dfbc 100644
--- a/include/VBox/err.h
+++ b/include/VBox/err.h
@@ -2488,7 +2488,7 @@
 #define VERR_SUP_VP_TOO_MANY_MEMORY_REGIONS          (-5645)
 /** Process Verficiation Failure: An image has too many sections. */
 #define VERR_SUP_VP_TOO_MANY_SECTIONS                (-5646)
-/** Process Verficiation Failure: An image is targetting an unexpected
+/** Process Verficiation Failure: An image is targeting an unexpected
  *  machine/CPU. */
 #define VERR_SUP_VP_UNEXPECTED_IMAGE_MACHINE         (-5647)
 /** Process Verficiation Failure: Unexpected section protection flag
@@ -2621,6 +2621,8 @@
 #define VERR_GIM_HYPERCALLS_NOT_ENABLED             (-6309)
 /** The GIM device is not registered with GIM when it ought to be. */
 #define VERR_GIM_DEVICE_NOT_REGISTERED              (-6310)
+/** Hypercall cannot be enabled/performed due to access/permissions/CPL. */
+#define VERR_GIM_HYPERCALL_ACCESS_DENIED            (-6311)
 /** @} */
 
 /** @name Main API Status Codes
diff --git a/include/VBox/err.mac b/include/VBox/err.mac
index e98e85a..6151626 100644
--- a/include/VBox/err.mac
+++ b/include/VBox/err.mac
@@ -123,6 +123,7 @@
 %define VINF_PATM_SPINLOCK_FAILED    (1429)
 %define VINF_PATCH_CONTINUE    (1430)
 %define VERR_PATM_HM_IPE    (-1431)
+%define VERR_PATM_IPE_TRAP_IN_PATCH_CODE    (-1432)
 %define VWRN_CSAM_TRAP_NOT_HANDLED    1500
 %define VWRN_CSAM_INSTRUCTION_PATCHED    1501
 %define VWRN_CSAM_PAGE_NOT_FOUND    1502
@@ -224,6 +225,8 @@
 %define VERR_CPUM_MSR_BAD_CPUMCPU_OFFSET    (-1757)
 %define VINF_CPUM_R3_MSR_READ    (1758)
 %define VINF_CPUM_R3_MSR_WRITE    (1759)
+%define VERR_TOO_MANY_CPUID_LEAVES    (1760)
+%define VERR_CPUM_INVALID_CONFIG_VALUE    (1761)
 %define VERR_SSM_UNIT_EXISTS    (-1800)
 %define VERR_SSM_UNIT_NOT_FOUND    (-1801)
 %define VERR_SSM_UNIT_NOT_OWNER    (-1802)
@@ -554,6 +557,7 @@
 %define VERR_VD_UNKNOWN_CFG_VALUES    (-3212)
 %define VERR_VD_UNKNOWN_INTERFACE    (-3213)
 %define VERR_VD_DEK_MISSING    (-3214)
+%define VERR_VD_PASSWORD_INCORRECT    (-3215)
 %define VERR_VD_GEN_INVALID_HEADER    (-3220)
 %define VERR_VD_VDI_INVALID_HEADER    (-3230)
 %define VERR_VD_VDI_INVALID_SIGNATURE    (-3231)
@@ -608,6 +612,12 @@
 %define VERR_INTNET_INCOMPATIBLE_TRUNK    (-3603)
 %define VERR_INTNET_INCOMPATIBLE_FLAGS    (-3604)
 %define VERR_INTNET_FLT_VNIC_CREATE_FAILED    (-3605)
+%define VERR_INTNET_FLT_VNIC_LINK_ID_NOT_FOUND    (-3606)
+%define VERR_INTNET_FLT_VNIC_INIT_FAILED    (-3607)
+%define VERR_INTNET_FLT_VNIC_OPEN_FAILED    (-3608)
+%define VERR_INTNET_FLT_LOWER_LINK_INFO_NOT_FOUND    (-3609)
+%define VERR_INTNET_FLT_LOWER_LINK_OPEN_FAILED    (-3610)
+%define VERR_INTNET_FLT_LOWER_LINK_ID_NOT_FOUND    (-3611)
 %define VERR_SUPDRV_COMPONENT_NOT_FOUND    (-3700)
 %define VERR_SUPDRV_INTERFACE_NOT_SUPPORTED    (-3701)
 %define VERR_SUPDRV_SERVICE_NOT_FOUND    (-3702)
@@ -654,6 +664,8 @@
 %define VERR_SUPDRV_TSC_DELTA_MEASUREMENT_FAILED    (-3743)
 %define VERR_SUPDRV_TSC_FREQ_MEASUREMENT_FAILED    (-3744)
 %define VERR_SUPDRV_TSC_READ_FAILED    (-3745)
+%define VWRN_SUPDRV_TSC_DELTA_MEASUREMENT_FAILED    3746
+%define VERR_SUPDRV_TSC_DELTA_MEASUREMENT_BUSY    (-3747)
 %define VERR_SUPLIB_PATH_NOT_ABSOLUTE    (-3750)
 %define VERR_SUPLIB_PATH_NOT_CLEAN    (-3751)
 %define VERR_SUPLIB_PATH_TOO_LONG    (-3752)
@@ -962,7 +974,7 @@
 %define VERR_GIM_HYPERCALLS_NOT_AVAILABLE    (-6308)
 %define VERR_GIM_HYPERCALLS_NOT_ENABLED    (-6309)
 %define VERR_GIM_DEVICE_NOT_REGISTERED    (-6310)
-%define VERR_GIM_INVALID_GUESTOS_ID    (-6311)
+%define VERR_GIM_HYPERCALL_ACCESS_DENIED    (-6311)
 %define VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR    (-6400)
 %define VERR_MAIN_CONFIG_CONSTRUCTOR_IPE    (-6401)
 %include "iprt/err.mac"
diff --git a/include/VBox/log.h b/include/VBox/log.h
index 2f79901..0e5182d 100644
--- a/include/VBox/log.h
+++ b/include/VBox/log.h
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -203,6 +203,8 @@ typedef enum LOGGROUP
     LOG_GROUP_DRV_SCSI,
     /** Host SCSI driver group. */
     LOG_GROUP_DRV_SCSIHOST,
+    /** TCP socket stream driver group. */
+    LOG_GROUP_DRV_TCP,
     /** Async transport driver group */
     LOG_GROUP_DRV_TRANSPORT_ASYNC,
     /** TUN network transport driver group */
@@ -562,6 +564,8 @@ typedef enum LOGGROUP
     /** Main group, ISnapshotEvent. */
     LOG_GROUP_MAIN_SNAPSHOTEVENT,
     /** Main group, ISnapshotTakenEvent. */
+    LOG_GROUP_MAIN_SNAPSHOTRESTOREDEVENT,
+    /** Main group, ISnapshotRestoredEvent. */
     LOG_GROUP_MAIN_SNAPSHOTTAKENEVENT,
     /** Main group, IStateChangedEvent. */
     LOG_GROUP_MAIN_STATECHANGEDEVENT,
@@ -846,6 +850,7 @@ typedef enum LOGGROUP
     "DRV_RAW_IMAGE", \
     "DRV_SCSI",     \
     "DRV_SCSIHOST", \
+    "DRV_TELNETSERVER", \
     "DRV_TRANSPORT_ASYNC", \
     "DRV_TUN",      \
     "DRV_UDPTUNNEL", \
@@ -1025,6 +1030,7 @@ typedef enum LOGGROUP
     "MAIN_SNAPSHOTCHANGEDEVENT", \
     "MAIN_SNAPSHOTDELETEDEVENT", \
     "MAIN_SNAPSHOTEVENT", \
+    "MAIN_SNAPSHOTRESTOREDEVENT", \
     "MAIN_SNAPSHOTTAKENEVENT", \
     "MAIN_STATECHANGEDEVENT", \
     "MAIN_STORAGECONTROLLER", \
diff --git a/include/VBox/sup.h b/include/VBox/sup.h
index 846ce9c..d4b781d 100644
--- a/include/VBox/sup.h
+++ b/include/VBox/sup.h
@@ -695,6 +695,27 @@ DECLINLINE(const char *) SUPGetGIPModeName(PSUPGLOBALINFOPAGE pGip)
 
 
 /**
+ * Gets the descriptive TSC-delta enum name.
+ *
+ * @returns The name.
+ * @param   pGip      Pointer to the GIP.
+ */
+DECLINLINE(const char *) SUPGetGIPTscDeltaModeName(PSUPGLOBALINFOPAGE pGip)
+{
+    AssertReturn(pGip, NULL);
+    switch (pGip->enmUseTscDelta)
+    {
+        case SUPGIPUSETSCDELTA_NOT_APPLICABLE:   return "Not Applicable";
+        case SUPGIPUSETSCDELTA_ZERO_CLAIMED:     return "Zero Claimed";
+        case SUPGIPUSETSCDELTA_PRACTICALLY_ZERO: return "Pratically Zero";
+        case SUPGIPUSETSCDELTA_ROUGHLY_ZERO:     return "Roughly Zero";
+        case SUPGIPUSETSCDELTA_NOT_ZERO:         return "Not Zero";
+        default:                                 return "???";
+    }
+}
+
+
+/**
  * Request for generic VMMR0Entry calls.
  */
 typedef struct SUPVMMR0REQHDR
diff --git a/include/VBox/vmm/cpum.h b/include/VBox/vmm/cpum.h
index 79e04c6..244bc5a 100644
--- a/include/VBox/vmm/cpum.h
+++ b/include/VBox/vmm/cpum.h
@@ -67,6 +67,8 @@ typedef enum CPUMCPUIDFEATURE
     CPUMCPUIDFEATURE_HVP,
     /** The MWait Extensions bits (Std) */
     CPUMCPUIDFEATURE_MWAIT_EXTS,
+    /** The CR4.OSXSAVE bit CPUID mirroring, only use from CPUMSetGuestCR4. */
+    CPUMCPUIDFEATURE_OSXSAVE,
     /** 32bit hackishness. */
     CPUMCPUIDFEATURE_32BIT_HACK = 0x7fffffff
 } CPUMCPUIDFEATURE;
@@ -309,8 +311,10 @@ typedef CPUMCPUIDLEAF const *PCCPUMCPUIDLEAF;
 #define CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES    RT_BIT_32(0)
 /** The leaf contains an APIC ID that needs changing to that of the current CPU. */
 #define CPUMCPUIDLEAF_F_CONTAINS_APIC_ID            RT_BIT_32(1)
+/** The leaf contains an OSXSAVE which needs individual handling on each CPU. */
+#define CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE            RT_BIT_32(2)
 /** Mask of the valid flags. */
-#define CPUMCPUIDLEAF_F_VALID_MASK                  UINT32_C(0x3)
+#define CPUMCPUIDLEAF_F_VALID_MASK                  UINT32_C(0x7)
 /** @} */
 
 /**
@@ -888,6 +892,124 @@ typedef CPUMMSRRANGE *PCPUMMSRRANGE;
 typedef CPUMMSRRANGE const *PCCPUMMSRRANGE;
 
 
+/**
+ * CPU features and quirks.
+ * This is mostly exploded CPUID info.
+ */
+typedef struct CPUMFEATURES
+{
+    /** The CPU vendor (CPUMCPUVENDOR). */
+    uint8_t         enmCpuVendor;
+    /** The CPU family. */
+    uint8_t         uFamily;
+    /** The CPU model. */
+    uint8_t         uModel;
+    /** The CPU stepping. */
+    uint8_t         uStepping;
+    /** The microarchitecture. */
+#ifndef VBOX_FOR_DTRACE_LIB
+    CPUMMICROARCH   enmMicroarch;
+#else
+    uint32_t        enmMicroarch;
+#endif
+    /** The maximum physical address with of the CPU. */
+    uint8_t         cMaxPhysAddrWidth;
+    /** Alignment padding. */
+    uint8_t         abPadding[1];
+    /** Max size of the extended state (or FPU state if no XSAVE). */
+    uint16_t        cbMaxExtendedState;
+
+    /** Supports MSRs. */
+    uint32_t        fMsr : 1;
+    /** Supports the page size extension (4/2 MB pages). */
+    uint32_t        fPse : 1;
+    /** Supports 36-bit page size extension (4 MB pages can map memory above
+     *  4GB). */
+    uint32_t        fPse36 : 1;
+    /** Supports physical address extension (PAE). */
+    uint32_t        fPae : 1;
+    /** Page attribute table (PAT) support (page level cache control). */
+    uint32_t        fPat : 1;
+    /** Supports the FXSAVE and FXRSTOR instructions. */
+    uint32_t        fFxSaveRstor : 1;
+    /** Supports the XSAVE and XRSTOR instructions. */
+    uint32_t        fXSaveRstor : 1;
+    /** The XSAVE/XRSTOR bit in CR4 has been set (only applicable for host!). */
+    uint32_t        fOpSysXSaveRstor : 1;
+    /** Supports MMX. */
+    uint32_t        fMmx : 1;
+    /** Supports AMD extensions to MMX instructions. */
+    uint32_t        fAmdMmxExts : 1;
+    /** Supports SSE. */
+    uint32_t        fSse : 1;
+    /** Supports SSE2. */
+    uint32_t        fSse2 : 1;
+    /** Supports SSE3. */
+    uint32_t        fSse3 : 1;
+    /** Supports SSSE3. */
+    uint32_t        fSsse3 : 1;
+    /** Supports SSE4.1. */
+    uint32_t        fSse41 : 1;
+    /** Supports SSE4.2. */
+    uint32_t        fSse42 : 1;
+    /** Supports AVX. */
+    uint32_t        fAvx : 1;
+    /** Supports AVX2. */
+    uint32_t        fAvx2 : 1;
+    /** Supports AVX512 foundation. */
+    uint32_t        fAvx512Foundation : 1;
+    /** Supports RDTSC. */
+    uint32_t        fTsc : 1;
+    /** Intel SYSENTER/SYSEXIT support */
+    uint32_t        fSysEnter : 1;
+    /** First generation APIC. */
+    uint32_t        fApic : 1;
+    /** Second generation APIC. */
+    uint32_t        fX2Apic : 1;
+    /** Hypervisor present. */
+    uint32_t        fHypervisorPresent : 1;
+    /** MWAIT & MONITOR instructions supported. */
+    uint32_t        fMonitorMWait : 1;
+    /** MWAIT Extensions present. */
+    uint32_t        fMWaitExtensions : 1;
+
+    /** Supports AMD 3DNow instructions. */
+    uint32_t        f3DNow : 1;
+    /** Supports the 3DNow/AMD64 prefetch instructions (could be nops). */
+    uint32_t        f3DNowPrefetch : 1;
+
+    /** AMD64: Supports long mode. */
+    uint32_t        fLongMode : 1;
+    /** AMD64: SYSCALL/SYSRET support. */
+    uint32_t        fSysCall : 1;
+    /** AMD64: No-execute page table bit. */
+    uint32_t        fNoExecute : 1;
+    /** AMD64: Supports LAHF & SAHF instructions in 64-bit mode. */
+    uint32_t        fLahfSahf : 1;
+    /** AMD64: Supports RDTSCP. */
+    uint32_t        fRdTscP : 1;
+    /** AMD64: Supports MOV CR8 in 32-bit code (lock prefix hack). */
+    uint32_t        fMovCr8In32Bit : 1;
+
+    /** Indicates that FPU instruction and data pointers may leak.
+     * This generally applies to recent AMD CPUs, where the FPU IP and DP pointer
+     * is only saved and restored if an exception is pending. */
+    uint32_t        fLeakyFxSR : 1;
+
+    /** Alignment padding / reserved for future use. */
+    uint32_t        fPadding : 29;
+    uint32_t        auPadding[3];
+} CPUMFEATURES;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(CPUMFEATURES, 32);
+#endif
+/** Pointer to a CPU feature structure. */
+typedef CPUMFEATURES *PCPUMFEATURES;
+/** Pointer to a const CPU feature structure. */
+typedef CPUMFEATURES const *PCCPUMFEATURES;
+
+
+
 /** @name Guest Register Getters.
  * @{ */
 VMMDECL(void)       CPUMGetGuestGDTR(PVMCPU pVCpu, PVBOXGDTR pGDTR);
diff --git a/include/VBox/vmm/cpum.mac b/include/VBox/vmm/cpum.mac
index 6f54f76..d08007e 100644
--- a/include/VBox/vmm/cpum.mac
+++ b/include/VBox/vmm/cpum.mac
@@ -234,9 +234,12 @@ struc CPUMCTX
     .msrKERNELGSBASE    resb    8
     .msrApicBase        resb    8
     alignb 8
+    .aXcr               resq    2
+    .fXStateMask        resq    1
     .pXStateR0      RTR0PTR_RES 1
     .pXStateR3      RTR3PTR_RES 1
     .pXStateRC      RTRCPTR_RES 1
+    .aoffXState         resw    64
     alignb 64
 endstruc
 
diff --git a/include/VBox/vmm/cpumctx.h b/include/VBox/vmm/cpumctx.h
index 785b61f..7bfb1ff 100644
--- a/include/VBox/vmm/cpumctx.h
+++ b/include/VBox/vmm/cpumctx.h
@@ -398,15 +398,23 @@ typedef struct CPUMCTX
     uint64_t        msrApicBase;        /**< The local APIC base (IA32_APIC_BASE MSR). */
     /** @} */
 
+    /** The XCR0..XCR1 registers. */
+    uint64_t                    aXcr[2];
+    /** The mask to pass to XSAVE/XRSTOR in EDX:EAX.  If zero we use
+     *  FXSAVE/FXRSTOR (since bit 0 will always be set, we only need to test it). */
+    uint64_t                    fXStateMask;
+
     /** Pointer to the FPU/SSE/AVX/XXXX state ring-0 mapping. */
     R0PTRTYPE(PX86XSAVEAREA)    pXStateR0;
     /** Pointer to the FPU/SSE/AVX/XXXX state ring-3 mapping. */
     R3PTRTYPE(PX86XSAVEAREA)    pXStateR3;
     /** Pointer to the FPU/SSE/AVX/XXXX state raw-mode mapping. */
     RCPTRTYPE(PX86XSAVEAREA)    pXStateRC;
+    /** State component offsets into pXState, UINT16_MAX if not present. */
+    uint16_t                    aoffXState[64];
 
     /** Size padding. */
-    uint32_t        au32SizePadding[HC_ARCH_BITS == 32 ? 3 : 1];
+    uint32_t        au32SizePadding[HC_ARCH_BITS == 32 ? 13 : 11];
 } CPUMCTX;
 #pragma pack()
 
@@ -419,7 +427,7 @@ AssertCompileSizeAlignment(CPUMCTX, 64);
 # define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax)
 
 /**
- * Gets the CPUMCTXCORE part of a CPUMCTX.
+ * Gets the CPUMCTX part from a CPUMCTXCORE.
  */
 # define CPUMCTX_FROM_CORE(a_pCtxCore) RT_FROM_MEMBER(a_pCtxCore, CPUMCTX, rax)
 
diff --git a/include/VBox/vmm/em.h b/include/VBox/vmm/em.h
index 380a763..5a57e9c 100644
--- a/include/VBox/vmm/em.h
+++ b/include/VBox/vmm/em.h
@@ -192,10 +192,6 @@ VMM_INT_DECL(VBOXSTRICTRC)      EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTX
 VMM_INT_DECL(int)               EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
 VMM_INT_DECL(int)               EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen);
 VMM_INT_DECL(int)               EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx);
-VMM_INT_DECL(int)               EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen);
-VMM_INT_DECL(int)               EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx);
-VMM_INT_DECL(int)               EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data);
-VMM_INT_DECL(int)               EMInterpretCLTS(PVM pVM, PVMCPU pVCpu);
 VMM_INT_DECL(int)               EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
 VMM_INT_DECL(int)               EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
 VMM_INT_DECL(bool)              EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx);
diff --git a/include/VBox/vmm/gim.h b/include/VBox/vmm/gim.h
index 0226000..bcd01b3 100644
--- a/include/VBox/vmm/gim.h
+++ b/include/VBox/vmm/gim.h
@@ -173,8 +173,8 @@ VMMDECL(GIMPROVIDERID)      GIMGetProvider(PVM pVM);
 VMM_INT_DECL(bool)          GIMIsParavirtTscEnabled(PVM pVM);
 VMM_INT_DECL(bool)          GIMAreHypercallsEnabled(PVMCPU pVCpu);
 VMM_INT_DECL(int)           GIMHypercall(PVMCPU pVCpu, PCPUMCTX pCtx);
-VMM_INT_DECL(int)           GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx);
-VMM_INT_DECL(bool)          GIMShouldTrapXcptUD(PVM pVM);
+VMM_INT_DECL(int)           GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis);
+VMM_INT_DECL(bool)          GIMShouldTrapXcptUD(PVMCPU pVCpu);
 VMM_INT_DECL(VBOXSTRICTRC)  GIMReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue);
 VMM_INT_DECL(VBOXSTRICTRC)  GIMWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue);
 /** @} */
diff --git a/include/VBox/vmm/hm.h b/include/VBox/vmm/hm.h
index 81cd097..fa3b4e7 100644
--- a/include/VBox/vmm/hm.h
+++ b/include/VBox/vmm/hm.h
@@ -143,7 +143,8 @@ VMM_INT_DECL(bool)              HMHasPendingIrq(PVM pVM);
 VMM_INT_DECL(PX86PDPE)          HMGetPaePdpes(PVMCPU pVCpu);
 VMM_INT_DECL(int)               HMAmdIsSubjectToErratum170(uint32_t *pu32Family, uint32_t *pu32Model, uint32_t *pu32Stepping);
 VMM_INT_DECL(bool)              HMSetSingleInstruction(PVMCPU pVCpu, bool fEnable);
-VMM_INT_DECL(int)               HMPatchHypercall(PVM pVM, void *pvBuf, size_t cbBuf, size_t *pcbWritten);
+VMM_INT_DECL(void)              HMHypercallsEnable(PVMCPU pVCpu);
+VMM_INT_DECL(void)              HMHypercallsDisable(PVMCPU pVCpu);
 
 #ifndef IN_RC
 VMM_INT_DECL(int)               HMFlushTLB(PVMCPU pVCpu);
@@ -207,6 +208,8 @@ VMMR0_INT_DECL(int)             HMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMC
 VMMR0_INT_DECL(int)             HMR0TestSwitcher3264(PVM pVM);
 # endif
 
+VMMR0_INT_DECL(int)             HMR0EnsureCompleteBasicContext(PVMCPU pVCpu, PCPUMCTX pMixedCtx);
+
 /** @} */
 #endif /* IN_RING0 */
 
diff --git a/include/VBox/vmm/hm_vmx.h b/include/VBox/vmm/hm_vmx.h
index ad92b71..b583a5e 100644
--- a/include/VBox/vmm/hm_vmx.h
+++ b/include/VBox/vmm/hm_vmx.h
@@ -981,10 +981,6 @@ typedef VMXMSRS *PVMXMSRS;
 #define VMX_EXIT_INVPCID                                        58
 /** 59 VMFUNC. Guest software attempted to execute VMFUNC. */
 #define VMX_EXIT_VMFUNC                                         59
-#if 1
-/** The maximum exit value (inclusive). */
-#define VMX_EXIT_MAX                                            (VMX_EXIT_VMFUNC)
-#else
 /** 60 ??? */
 #define VMX_EXIT_RESERVED_60                                    60
 /** 61 - RDSEED - Guest software attempted to executed RDSEED and exiting was
@@ -1000,7 +996,6 @@ typedef VMXMSRS *PVMXMSRS;
 #define VMX_EXIT_XRSTORS                                        64
 /** The maximum exit value (inclusive). */
 #define VMX_EXIT_MAX                                            (VMX_EXIT_XRSTORS)
-#endif
 /** @} */
 
 
diff --git a/include/VBox/vmm/iem.h b/include/VBox/vmm/iem.h
index 50ba407..6c298f2 100644
--- a/include/VBox/vmm/iem.h
+++ b/include/VBox/vmm/iem.h
@@ -50,6 +50,16 @@ typedef enum IEMMODE
 AssertCompileSize(IEMMODE, 4);
 
 
+/** @name IEM status codes.
+ *
+ * Not quite sure how this will play out in the end, just aliasing safe status
+ * codes for now.
+ *
+ * @{ */
+#define VINF_IEM_RAISED_XCPT    VINF_EM_RESCHEDULE
+/** @} */
+
+
 VMMDECL(VBOXSTRICTRC)       IEMExecOne(PVMCPU pVCpu);
 VMMDECL(VBOXSTRICTRC)       IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
 VMMDECL(VBOXSTRICTRC)       IEMExecOneWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC,
@@ -71,6 +81,10 @@ VMM_INT_DECL(VBOXSTRICTRC)  IEMExecStringIoWrite(PVMCPU pVCpu, uint8_t cbValue,
                                                  bool fRepPrefix, uint8_t cbInstr, uint8_t iEffSeg);
 VMM_INT_DECL(VBOXSTRICTRC)  IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
                                                 bool fRepPrefix, uint8_t cbInstr);
+VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedMovCRxWrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iCrReg, uint8_t iGReg);
+VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedMovCRxRead(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iGReg, uint8_t iCrReg);
+VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedClts(PVMCPU pVCpu, uint8_t cbInstr);
+VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uValue);
 /** @}  */
 
 #if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
diff --git a/include/VBox/vmm/vm.h b/include/VBox/vmm/vm.h
index 0328e1a..9050e4a 100644
--- a/include/VBox/vmm/vm.h
+++ b/include/VBox/vmm/vm.h
@@ -977,6 +977,18 @@ typedef struct VM
 #ifdef ___CPUMInternal_h
         struct CPUM s;
 #endif
+#ifdef ___VBox_vmm_cpum_h
+        /** Read only info exposed about the host and guest CPUs.   */
+        struct
+        {
+            /** Padding for hidden fields. */
+            uint8_t                 abHidden0[64];
+            /** Host CPU feature information. */
+            CPUMFEATURES            HostFeatures;
+            /** Guest CPU feature information. */
+            CPUMFEATURES            GuestFeatures;
+        } const ro;
+#endif
         uint8_t     padding[1536];      /* multiple of 64 */
     } cpum;
 
diff --git a/include/VBox/vmm/vmm.h b/include/VBox/vmm/vmm.h
index e505bc9..c1f5650 100644
--- a/include/VBox/vmm/vmm.h
+++ b/include/VBox/vmm/vmm.h
@@ -267,6 +267,9 @@ VMM_INT_DECL(uint32_t)      VMMGetSvnRev(void);
 VMM_INT_DECL(VMMSWITCHER)   VMMGetSwitcher(PVM pVM);
 VMM_INT_DECL(bool)          VMMIsInRing3Call(PVMCPU pVCpu);
 VMM_INT_DECL(void)          VMMTrashVolatileXMMRegs(void);
+VMM_INT_DECL(int)           VMMPatchHypercall(PVM pVM, void *pvBuf, size_t cbBuf, size_t *pcbWritten);
+VMM_INT_DECL(void)          VMMHypercallsEnable(PVMCPU pVCpu);
+VMM_INT_DECL(void)          VMMHypercallsDisable(PVMCPU pVCpu);
 
 
 #if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
diff --git a/include/iprt/asm-amd64-x86.h b/include/iprt/asm-amd64-x86.h
index 4d5c090..0f6a4c1 100644
--- a/include/iprt/asm-amd64-x86.h
+++ b/include/iprt/asm-amd64-x86.h
@@ -1726,6 +1726,20 @@ DECLINLINE(RTCCUINTREG) ASMGetCR8(void)
 
 
 /**
+ * Get XCR0 (eXtended feature Control Register 0).
+ * @returns xcr0.
+ */
+DECLASM(uint64_t) ASMGetXcr0(void);
+
+
+/**
+ * Sets the XCR0 register.
+ * @param   uXcr0   The new XCR0 value.
+ */
+DECLASM(void) ASMSetXcr0(uint64_t uXcr0);
+
+
+/**
  * Enables interrupts (EFLAGS.IF).
  */
 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
diff --git a/include/iprt/assert.h b/include/iprt/assert.h
index 8b9fba0..32ed30b 100644
--- a/include/iprt/assert.h
+++ b/include/iprt/assert.h
@@ -1613,7 +1613,7 @@ RT_C_DECLS_END
     do { \
         if (RT_UNLIKELY(!(expr))) \
         { \
-            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg1Weak(#expr, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
             RTAssertReleasePanic(); \
         } \
     } while (0)
@@ -1828,7 +1828,7 @@ RT_C_DECLS_END
  */
 #define AssertReleaseMsgFailed(a)  \
     do { \
-        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+        RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
         RTAssertMsg2Weak a; \
         RTAssertReleasePanic(); \
     } while (0)
@@ -1939,7 +1939,7 @@ RT_C_DECLS_END
     do { \
         for (;;) \
         { \
-            RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
             RTAssertReleasePanic(); \
         } \
     } while (0)
@@ -1953,7 +1953,7 @@ RT_C_DECLS_END
     do { \
         for (;;) \
         { \
-            RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+            RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__); \
             RTAssertMsg2Weak a; \
             RTAssertReleasePanic(); \
         } \
diff --git a/include/iprt/cdefs.h b/include/iprt/cdefs.h
index f741d16..ca58a9f 100644
--- a/include/iprt/cdefs.h
+++ b/include/iprt/cdefs.h
@@ -320,7 +320,7 @@
 /** @} */
 
 /** @def RT_OPSYS
- * Indicates which OS we're targetting. It's a \#define with is
+ * Indicates which OS we're targeting. It's a \#define with is
  * assigned one of the RT_OPSYS_XXX defines above.
  *
  * So to test if we're on FreeBSD do the following:
@@ -2637,7 +2637,7 @@
 
 
 /** Source position. */
-#define RT_SRC_POS         __FILE__, __LINE__, __PRETTY_FUNCTION__
+#define RT_SRC_POS         __FILE__, __LINE__, RT_GCC_EXTENSION __PRETTY_FUNCTION__
 
 /** Source position declaration. */
 #define RT_SRC_POS_DECL    const char *pszFile, unsigned iLine, const char *pszFunction
diff --git a/include/iprt/err.h b/include/iprt/err.h
index b1215ca..c6c14b9 100644
--- a/include/iprt/err.h
+++ b/include/iprt/err.h
@@ -1016,25 +1016,25 @@ RT_C_DECLS_END
 #define VERR_FILE_AIO_NOT_PREPARED          (-136)
 /** Not all requests could be submitted due to resource shortage. */
 #define VERR_FILE_AIO_INSUFFICIENT_RESSOURCES (-137)
-/** There are not enough events available on the host to create the I/O context.
- * This exact meaning is host platform dependent. */
-#define VERR_FILE_AIO_INSUFFICIENT_EVENTS   (-138)
 /** Device or resource is busy. */
-#define VERR_RESOURCE_BUSY                  (-139)
+#define VERR_RESOURCE_BUSY                  (-138)
 /** A file operation was attempted on a non-file object. */
-#define VERR_NOT_A_FILE                     (-140)
+#define VERR_NOT_A_FILE                     (-139)
 /** A non-file operation was attempted on a file object. */
-#define VERR_IS_A_FILE                      (-141)
+#define VERR_IS_A_FILE                      (-140)
 /** Unexpected filesystem object type. */
-#define VERR_UNEXPECTED_FS_OBJ_TYPE         (-142)
+#define VERR_UNEXPECTED_FS_OBJ_TYPE         (-141)
 /** A path does not start with a root specification. */
-#define VERR_PATH_DOES_NOT_START_WITH_ROOT  (-143)
+#define VERR_PATH_DOES_NOT_START_WITH_ROOT  (-142)
 /** A path is relative, expected an absolute path. */
-#define VERR_PATH_IS_RELATIVE               (-144)
+#define VERR_PATH_IS_RELATIVE               (-143)
 /** A path is not relative (start with root), expected an relative path. */
-#define VERR_PATH_IS_NOT_RELATIVE           (-145)
+#define VERR_PATH_IS_NOT_RELATIVE           (-144)
 /** Zero length path. */
-#define VERR_PATH_ZERO_LENGTH               (-146)
+#define VERR_PATH_ZERO_LENGTH               (-145)
+/** There are not enough events available on the host to create the I/O context.
+ * This exact meaning is host platform dependent. */
+#define VERR_FILE_AIO_INSUFFICIENT_EVENTS   (-146)
 /** @} */
 
 
diff --git a/include/iprt/err.mac b/include/iprt/err.mac
index 4d6f9e4..ab5fc9c 100644
--- a/include/iprt/err.mac
+++ b/include/iprt/err.mac
@@ -128,6 +128,8 @@
 %define VERR_UNABLE_TO_SATISFY_REQUIREMENTS    (-22406)
 %define VWRN_UNABLE_TO_SATISFY_REQUIREMENTS    22406
 %define VERR_ALLOCATION_TOO_BIG    (-22407)
+%define VERR_MISMATCH    (-22408)
+%define VERR_WRONG_TYPE    (-22409)
 %define VERR_FILE_IO_ERROR    (-100)
 %define VERR_OPEN_FAILED    (-101)
 %define VERR_FILE_NOT_FOUND    (-102)
@@ -176,6 +178,7 @@
 %define VERR_PATH_IS_RELATIVE    (-143)
 %define VERR_PATH_IS_NOT_RELATIVE    (-144)
 %define VERR_PATH_ZERO_LENGTH    (-145)
+%define VERR_FILE_AIO_INSUFFICIENT_EVENTS    (-146)
 %define VERR_DISK_IO_ERROR    (-150)
 %define VERR_INVALID_DRIVE    (-151)
 %define VERR_DISK_FULL    (-152)
@@ -405,6 +408,8 @@
 %define VWRN_ENV_NOT_FULLY_TRANSLATED    (751)
 %define VERR_CPU_OFFLINE    (-800)
 %define VERR_CPU_NOT_FOUND    (-801)
+%define VERR_NOT_ALL_CPUS_SHOWED    (-802)
+%define VERR_CPU_IPE_1    (-803)
 %define VERR_GETOPT_UNKNOWN_OPTION    (-825)
 %define VERR_GETOPT_REQUIRED_ARGUMENT_MISSING    (-826)
 %define VERR_GETOPT_INVALID_ARGUMENT_FORMAT    (-827)
diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h
index 8b81a7a..5f2cb21 100644
--- a/include/iprt/mangling.h
+++ b/include/iprt/mangling.h
@@ -71,8 +71,12 @@
 # define ASMAtomicXchgU64_EndProc                       RT_MANGLER(ASMAtomicXchgU64_EndProc)
 # define ASMCpuIdExSlow                                 RT_MANGLER(ASMCpuIdExSlow)
 # define ASMCpuIdExSlow_EndProc                         RT_MANGLER(ASMCpuIdExSlow_EndProc)
+# define ASMGetXcr0                                     RT_MANGLER(ASMGetXcr0)
+# define ASMGetXcr0_EndProc                             RT_MANGLER(ASMGetXcr0_EndProc)
 # define ASMRdMsrEx                                     RT_MANGLER(ASMRdMsrEx)
 # define ASMRdMsrEx_EndProc                             RT_MANGLER(ASMRdMsrEx_EndProc)
+# define ASMSetXcr0                                     RT_MANGLER(ASMSetXcr0)
+# define ASMSetXcr0_EndProc                             RT_MANGLER(ASMSetXcr0_EndProc)
 # define ASMWrMsrEx                                     RT_MANGLER(ASMWrMsrEx)
 # define ASMWrMsrEx_EndProc                             RT_MANGLER(ASMWrMsrEx_EndProc)
 # define RTAssertAreQuiet                               RT_MANGLER(RTAssertAreQuiet)
diff --git a/include/iprt/nt/nt.h b/include/iprt/nt/nt.h
index a7b6823..26b14aa 100644
--- a/include/iprt/nt/nt.h
+++ b/include/iprt/nt/nt.h
@@ -222,7 +222,7 @@
 
 /** @name Useful macros
  * @{ */
-/** Indicates that we're targetting native NT in the current source. */
+/** Indicates that we're targeting native NT in the current source. */
 #define RTNT_USE_NATIVE_NT              1
 /** Initializes a IO_STATUS_BLOCK. */
 #define RTNT_IO_STATUS_BLOCK_INITIALIZER  { STATUS_FAILED_DRIVER_ENTRY, ~(uintptr_t)42 }
diff --git a/include/iprt/x86.mac b/include/iprt/x86.mac
index e860183..4580c32 100644
--- a/include/iprt/x86.mac
+++ b/include/iprt/x86.mac
@@ -67,6 +67,7 @@
 %define X86_CPUID_FEATURE_ECX_TM2       RT_BIT(8)
 %define X86_CPUID_FEATURE_ECX_SSSE3     RT_BIT(9)
 %define X86_CPUID_FEATURE_ECX_CNTXID    RT_BIT(10)
+%define X86_CPUID_FEATURE_ECX_SDBG      RT_BIT(11)
 %define X86_CPUID_FEATURE_ECX_FMA       RT_BIT(12)
 %define X86_CPUID_FEATURE_ECX_CX16      RT_BIT(13)
 %define X86_CPUID_FEATURE_ECX_TPRUPDATE RT_BIT(14)
@@ -141,6 +142,7 @@
 %define X86_CPUID_STEXT_FEATURE_EBX_AVX512ER          RT_BIT(27)
 %define X86_CPUID_STEXT_FEATURE_EBX_AVX512CD          RT_BIT(28)
 %define X86_CPUID_STEXT_FEATURE_EBX_SHA               RT_BIT(29)
+%define X86_CPUID_STEXT_FEATURE_ECX_PREFETCHWT1       RT_BIT(0)
 %define X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF     RT_BIT(0)
 %define X86_CPUID_EXT_FEATURE_EDX_SYSCALL       RT_BIT(11)
 %define X86_CPUID_EXT_FEATURE_EDX_NX            RT_BIT(20)
@@ -182,6 +184,11 @@
 %define X86_CPUID_AMD_FEATURE_ECX_XOP       RT_BIT(11)
 %define X86_CPUID_AMD_FEATURE_ECX_SKINIT    RT_BIT(12)
 %define X86_CPUID_AMD_FEATURE_ECX_WDT       RT_BIT(13)
+%define X86_CPUID_AMD_FEATURE_ECX_LWP       RT_BIT(15)
+%define X86_CPUID_AMD_FEATURE_ECX_FMA4      RT_BIT(16)
+%define X86_CPUID_AMD_FEATURE_ECX_NODEID    RT_BIT(19)
+%define X86_CPUID_AMD_FEATURE_ECX_TBM       RT_BIT(21)
+%define X86_CPUID_AMD_FEATURE_ECX_TOPOEXT   RT_BIT(22)
 %define X86_CPUID_AMD_ADVPOWER_EDX_TS        RT_BIT(0)
 %define X86_CPUID_AMD_ADVPOWER_EDX_FID       RT_BIT(1)
 %define X86_CPUID_AMD_ADVPOWER_EDX_VID       RT_BIT(2)
@@ -191,6 +198,10 @@
 %define X86_CPUID_AMD_ADVPOWER_EDX_MC        RT_BIT(6)
 %define X86_CPUID_AMD_ADVPOWER_EDX_HWPSTATE  RT_BIT(7)
 %define X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR  RT_BIT(8)
+%define X86_CPUID_AMD_ADVPOWER_EDX_CPB       RT_BIT(9)
+%define X86_CPUID_AMD_ADVPOWER_EDX_EFRO      RT_BIT(10)
+%define X86_CPUID_AMD_ADVPOWER_EDX_PFI       RT_BIT(11)
+%define X86_CPUID_AMD_ADVPOWER_EDX_PA        RT_BIT(12)
 %define X86_CR0_PE                          RT_BIT(0)
 %define X86_CR0_PROTECTION_ENABLE           RT_BIT(0)
 %define X86_CR0_MP                          RT_BIT(1)
@@ -285,8 +296,10 @@
 %define X86_DR7_RW(iBp, fRw)                ( (fRw) << ((iBp) * 4 + 16) )
 %define X86_DR7_GET_RW(uDR7, iBp)            ( ( (uDR7) >> ((iBp) * 4 + 16) ) & 3 )
 %define X86_DR7_RW_ALL_MASKS                0x33330000
-%define X86_DR7_ANY_RW_IO(uDR7) \
+%ifndef VBOX_FOR_DTRACE_LIB
+ %define X86_DR7_ANY_RW_IO(uDR7) \
     (   (    0x22220000 & (uDR7) )
+%endif
 %define X86_DR7_LEN_BYTE                    0
 %define X86_DR7_LEN_WORD                    1
 %define X86_DR7_LEN_QWORD                   2
@@ -586,8 +599,20 @@
 %define X86_PML4E_NX                        RT_BIT_64(63)
 %define X86_PML4_SHIFT              39
 %define X86_PML4_MASK               0x1ff
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
 %define X86_OFF_FXSTATE_RSVD            0x1d0
 %define X86_FXSTATE_RSVD_32BIT_MAGIC    0x32b3232b
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
 %define X86_FSW_IE          RT_BIT(0)
 %define X86_FSW_DE          RT_BIT(1)
 %define X86_FSW_ZE          RT_BIT(2)
@@ -649,6 +674,33 @@
 %define X86_MXSCR_MM          RT_BIT(17)
 %ifndef VBOX_FOR_DTRACE_LIB
 %endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%define XSAVE_C_X87         RT_BIT_64(0)
+%define XSAVE_C_SSE         RT_BIT_64(1)
+%define XSAVE_C_YMM         RT_BIT_64(2)
+%define XSAVE_C_BNDREGS     RT_BIT_64(3)
+%define XSAVE_C_BNDCSR      RT_BIT_64(4)
+%define XSAVE_C_OPMASK      RT_BIT_64(5)
+%define XSAVE_C_ZMM_HI256   RT_BIT_64(6)
+%define XSAVE_C_ZMM_16HI    RT_BIT_64(7)
+%define XSAVE_C_LWP         RT_BIT_64(62)
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
 %define X86DESCATTR_TYPE            0x0000000f
 %define X86DESCATTR_DT              0x00000010
 %define X86DESCATTR_DPL             0x00000060
diff --git a/src/VBox/Additions/common/crOpenGL/DD_glc.py b/src/VBox/Additions/common/crOpenGL/DD_glc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/DD_glh.py b/src/VBox/Additions/common/crOpenGL/DD_glh.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/NULLfuncs.py b/src/VBox/Additions/common/crOpenGL/NULLfuncs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/cr_gl.py b/src/VBox/Additions/common/crOpenGL/cr_gl.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/entrypoints.py b/src/VBox/Additions/common/crOpenGL/entrypoints.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/getprocaddress.py b/src/VBox/Additions/common/crOpenGL/getprocaddress.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/pack.py b/src/VBox/Additions/common/crOpenGL/pack/pack.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.py b/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/stub_common.py b/src/VBox/Additions/common/crOpenGL/stub_common.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/tsfuncs.py b/src/VBox/Additions/common/crOpenGL/tsfuncs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py b/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp b/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
index 1caa77a..5150f38 100644
--- a/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
@@ -2254,7 +2254,7 @@ int DragAndDropService::hgcmEventThread(RTTHREAD hThread, void *pvUser)
     uint32_t uClientID;
     int rc = VbglR3DnDConnect(&uClientID);
     if (RT_FAILURE(rc))
-        LogRel(("DnD: Unable to connect to drag'n drop service, rc=%Rrc\n", rc));
+        LogRel(("DnD: Unable to connect to drag and drop service, rc=%Rrc\n", rc));
     /* Not RT_FAILURE: VINF_PERMISSION_DENIED is host service not present. */
     if (rc != VINF_SUCCESS)
         return rc;
diff --git a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
index 15bd9ee..eeda60c 100644
--- a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
+++ b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
@@ -167,7 +167,7 @@ vboxvideo_drv_13_INCS = \
 	$(vboxvideo_xorg_INCS) \
 	$(VBOX_PATH_X11_ROOT)/xorg-server-1.3.0.0
 vboxvideo_drv_13_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
-vboxvideo_drv_13_SOURCES = $(vboxvideo_drv_SOURCES) edid.c
+vboxvideo_drv_13_SOURCES = $(vboxvideo_drv_SOURCES)
 
 
 #
diff --git a/src/VBox/Additions/x11/vboxvideo/edid.c b/src/VBox/Additions/x11/vboxvideo/edid.c
deleted file mode 100644
index fd7aff4..0000000
--- a/src/VBox/Additions/x11/vboxvideo/edid.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* $Id: edid.c $ */
-/** @file
- *
- * Linux Additions X11 graphics driver, EDID construction
- */
-
-/*
- * Copyright (C) 2006-2012 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- * --------------------------------------------------------------------
- *
- * This code is based on drmmode_display.c from the X.Org xf86-video-intel
- * driver with the following copyright notice:
- *
- * Copyright © 2007 Red Hat, Inc.
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Authors:
- *    Dave Airlie <airlied at redhat.com>
- */
-
-#include <misc.h>
-#include <xf86DDC.h>
-#include <xf86Crtc.h>
-#include "vboxvideo.h"
-
-enum { EDID_SIZE = 128 };
-
-const unsigned char g_acszEDIDBase[EDID_SIZE] =
-{
-   0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
-   0x58, 0x58, /* manufacturer (VBX) */
-   0x00, 0x00, /* product code */
-   0x00, 0x00,0x00, 0x00, /* serial number goes here */
-   0x01, /* week of manufacture */
-   0x00, /* year of manufacture */
-   0x01, 0x03, /* EDID version */
-   0x80, /* capabilities - digital */
-   0x00, /* horiz. res in cm, zero for projectors */
-   0x00, /* vert. res in cm */
-   0x78, /* display gamma (120 == 2.2).  Should we ask the host for this? */
-   0xEE, /* features (standby, suspend, off, RGB, standard colour space,
-          * preferred timing mode) */
-   0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
-       /* chromaticity for standard colour space - should we ask the host? */
-   0x00, 0x00, 0x00, /* no default timings */
-   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-   0x01, 0x01, 0x01, 0x01, /* no standard timings */
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
-   0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
-   0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
-   0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
-   0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
-   'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
-   0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
-   0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-   0x20,
-   0x00, /* number of extensions */
-   0x00 /* checksum goes here */
-};
-
-static void fillDescBlockTimings(unsigned char *pchDescBlock,
-                                 DisplayModePtr mode)
-{
-    struct detailed_timings timing;
-
-    timing.clock = mode->Clock * 1000;
-    timing.h_active = mode->HDisplay;
-    timing.h_blanking = mode->HTotal - mode->HDisplay;
-    timing.v_active = mode->VDisplay;
-    timing.v_blanking = mode->VTotal - mode->VDisplay;
-    timing.h_sync_off = mode->HSyncStart - mode->HDisplay;
-    timing.h_sync_width = mode->HSyncEnd - mode->HSyncStart;
-    timing.v_sync_off = mode->VSyncStart - mode->VDisplay;
-    timing.v_sync_width = mode->VSyncEnd - mode->VSyncStart;
-    pchDescBlock[0]   = (timing.clock / 10000) & 0xff;
-    pchDescBlock[1]   = (timing.clock / 10000) >> 8;
-    pchDescBlock[2]   = timing.h_active & 0xff;
-    pchDescBlock[3]   = timing.h_blanking & 0xff;
-    pchDescBlock[4]   = (timing.h_active >> 4) & 0xf0;
-    pchDescBlock[4]  |= (timing.h_blanking >> 8) & 0xf;
-    pchDescBlock[5]   = timing.v_active & 0xff;
-    pchDescBlock[6]   = timing.v_blanking & 0xff;
-    pchDescBlock[7]   = (timing.v_active >> 4) & 0xf0;
-    pchDescBlock[7]  |= (timing.v_blanking >> 8) & 0xf;
-    pchDescBlock[8]   = timing.h_sync_off & 0xff;
-    pchDescBlock[9]   = timing.h_sync_width & 0xff;
-    pchDescBlock[10]  = (timing.v_sync_off << 4) & 0xf0;
-    pchDescBlock[10] |= timing.v_sync_width & 0xf;
-    pchDescBlock[11]  = (timing.h_sync_off >> 2) & 0xC0;
-    pchDescBlock[11] |= (timing.h_sync_width >> 4) & 0x30;
-    pchDescBlock[11] |= (timing.v_sync_off >> 2) & 0xC;
-    pchDescBlock[11] |= (timing.v_sync_width >> 4) & 0x3;
-    pchDescBlock[12] = pchDescBlock[13] = pchDescBlock[14]
-                     = pchDescBlock[15] = pchDescBlock[16]
-                     = pchDescBlock[17] = 0;
-}
-
-
-static void setEDIDChecksum(unsigned char *pch)
-{
-    unsigned i, sum = 0;
-    for (i = 0; i < EDID_SIZE - 1; ++i)
-        sum += pch[i];
-    pch[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
-}
-
-
-/**
- * Construct an EDID for an output given a preferred mode.  The main reason for
- * doing this is to confound gnome-settings-deamon which tries to reset the
- * last mode configuration if the same monitors are plugged in again, which is
- * a reasonable thing to do but not what we want in a VM.  We evily store
- * the (empty) raw EDID data at the end of the structure so that it gets
- * freed automatically along with the structure.
- */
-Bool VBOXEDIDSet(xf86OutputPtr output, DisplayModePtr pmode)
-{
-    int i, j;
-    unsigned char *pch, *pchEDID;
-    xf86MonPtr pEDIDMon;
-
-    pch = calloc(1, sizeof(xf86Monitor) + EDID_SIZE);
-    if (!pch)
-    {
-        xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-            "Can't allocate memory for EDID structure.\n");
-        return FALSE;
-    }
-    pchEDID = pch + sizeof(xf86Monitor);
-    memcpy(pchEDID, g_acszEDIDBase, EDID_SIZE);
-    pchEDID[12] = pmode->HDisplay & 0xff;
-    pchEDID[13] = pmode->HDisplay >> 8;
-    pchEDID[14] = pmode->VDisplay & 0xff;
-    pchEDID[15] = pmode->VDisplay >> 8;
-    fillDescBlockTimings(pchEDID + 54, pmode);
-    setEDIDChecksum(pchEDID);
-    pEDIDMon = xf86InterpretEDID(output->scrn->scrnIndex, pchEDID);
-    if (!pEDIDMon)
-    {
-        free(pch);
-        return FALSE;
-    }
-    memcpy(pch, pEDIDMon, sizeof(xf86Monitor));
-    free(pEDIDMon);
-    pEDIDMon = (xf86MonPtr)pch;
-    xf86OutputSetEDID(output, pEDIDMon);
-    return TRUE;
-}
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
index 023427f..11c584c 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
@@ -149,7 +149,7 @@ static Bool VBOXMapVidMem(ScrnInfoPtr pScrn);
 static void VBOXUnmapVidMem(ScrnInfoPtr pScrn);
 static void VBOXSaveMode(ScrnInfoPtr pScrn);
 static void VBOXRestoreMode(ScrnInfoPtr pScrn);
-static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime, bool fVTSwitchTime);
+static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime);
 
 #ifndef XF86_SCRN_INTERFACE
 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum]
@@ -288,6 +288,9 @@ static Bool adjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
         return TRUE;
     pPixmap = pScreen->GetScreenPixmap(pScreen);
     VBVXASSERT(pPixmap != NULL, ("Failed to get the screen pixmap.\n"));
+    TRACE_LOG("pPixmap=%p adjustedWidth=%d height=%d pScrn->depth=%d pScrn->bitsPerPixel=%d cbLine=%d pVBox->base=%p pPixmap->drawable.width=%d pPixmap->drawable.height=%d\n",
+              pPixmap, adjustedWidth, height, pScrn->depth, pScrn->bitsPerPixel, cbLine, pVBox->base, pPixmap->drawable.width,
+              pPixmap->drawable.height);
     if (   adjustedWidth != pPixmap->drawable.width
         || height != pPixmap->drawable.height)
     {
@@ -1150,17 +1153,17 @@ static void setSizesRandR11(ScrnInfoPtr pScrn, bool fLimitedContext)
 
 #endif
 
-static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime, bool fVTSwitchTime)
+static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime)
 {
     VBOXPtr pVBox = VBOXGetRec(pScrn);
     
-    TRACE_LOG("fScreenInitTime=%d, fVTSwitchTime=%d\n", (int)fScreenInitTime, (int)fVTSwitchTime);
+    TRACE_LOG("fScreenInitTime=%d\n", (int)fScreenInitTime);
 #ifdef VBOXVIDEO_13
     setSizesRandR12(pScrn, fScreenInitTime);
 #else
     setSizesRandR11(pScrn, fScreenInitTime);
 #endif
-    if (!fVTSwitchTime)
+    if (pScrn->vtSema)
         vbvxReprobeCursor(pScrn);
 }
 
@@ -1182,7 +1185,7 @@ static void updateSizeHintsBlockHandler(pointer pData, OSTimePtr pTimeout, point
     if (ROOT_WINDOW(pScrn) != NULL)
         vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, &fNeedUpdate);
     if (fNeedUpdate)
-        setSizesAndCursorIntegration(pScrn, false, false);
+        setSizesAndCursorIntegration(pScrn, false);
 }
 
 /*
@@ -1331,7 +1334,7 @@ static Bool VBOXScreenInit(ScreenPtr pScreen, int argc, char **argv)
 
 #endif
     /* set first video mode */
-    setSizesAndCursorIntegration(pScrn, true, false);
+    setSizesAndCursorIntegration(pScrn, true);
 
     /* Register block and wake-up handlers for getting new screen size hints. */
     RegisterBlockAndWakeupHandlers(updateSizeHintsBlockHandler, (WakeupHandlerProcPtr)NoopDDA, (pointer)pScrn);
@@ -1400,7 +1403,14 @@ static Bool VBOXEnterVT(ScrnInfoPtr pScrn)
     /* Re-set video mode */
     vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL);
     vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL);
-    setSizesAndCursorIntegration(pScrn, false, true);
+    /* This prevents a crash in CentOS 3.  I was unable to debug it to
+     * satisfaction, partly due to the lack of symbols.  My guess is that
+     * pScrn->ModifyPixmapHeader() expects certain things to be set up when
+     * it sees pScrn->vtSema set to true which are not quite done at this
+     * point of the VT switch. */
+    pScrn->vtSema = FALSE;
+    setSizesAndCursorIntegration(pScrn, false);
+    pScrn->vtSema = TRUE;
 #ifdef SET_HAVE_VT_PROPERTY
     updateHasVTProperty(pScrn, TRUE);
 #endif
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo.h b/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
index a481f77..e0f331b 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
@@ -94,7 +94,7 @@ if (!(expr)) \
 { \
     vbvxMsg("\nAssertion failed!\n\n"); \
     vbvxMsg("%s\n", #expr); \
-    vbvxMsg("at %s (%s:%d)\n", __PRETTY_FUNCTION__, __FILE__, __LINE__); \
+    vbvxMsg("at %s (%s:%d)\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, __FILE__, __LINE__); \
     vbvxMsg out; \
     vbvxAbortServer(); \
 }
@@ -292,10 +292,5 @@ extern Bool VBOXDRIFinishScreenInit(ScreenPtr pScreen);
 extern void VBOXDRIUpdateStride(ScrnInfoPtr pScrn, VBOXPtr pVBox);
 extern void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox);
 
-/* EDID generation */
-#ifdef VBOXVIDEO_13
-extern Bool VBOXEDIDSet(struct _xf86Output *output, DisplayModePtr pmode);
-#endif
-
 #endif /* _VBOXVIDEO_H_ */
 
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c
index 1471a1b..33abb17 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c
@@ -181,7 +181,7 @@ Bool VBOXDRIScreenInit(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
         || (pVBox->cbFBMax == 0))
     {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: preconditions failed\n",
-                   __PRETTY_FUNCTION__);
+                   RT_GCC_EXTENSION __PRETTY_FUNCTION__);
         rc = FALSE;
     }
     /* Check that the GLX, DRI, and DRM modules have been loaded by testing for
diff --git a/src/VBox/Devices/Audio/AudioMixBuffer.cpp b/src/VBox/Devices/Audio/AudioMixBuffer.cpp
index 3840bf0..50e89bb 100644
--- a/src/VBox/Devices/Audio/AudioMixBuffer.cpp
+++ b/src/VBox/Devices/Audio/AudioMixBuffer.cpp
@@ -413,7 +413,7 @@ AUDMIXBUF_CONVERT(U32 /* Name */, uint32_t, 0         /* Min */, UINT32_MAX /* M
         PDMAUDIOSAMPLE  samCur = { 0 }; \
         PDMAUDIOSAMPLE  samOut; \
         PDMAUDIOSAMPLE  samLast    = pRate->srcSampleLast; \
-        uint64_t        lDelta; \
+        uint64_t        lDelta = 0; \
         \
         AUDMIXBUF_MACRO_LOG(("Start: paDstEnd=%p - paDstStart=%p -> %zu\n", paDstEnd, paDst, paDstEnd - paDstStart)); \
         AUDMIXBUF_MACRO_LOG(("Start: paSrcEnd=%p - paSrcStart=%p -> %zu\n", paSrcEnd, paSrc, paSrcEnd - paSrcStart)); \
diff --git a/src/VBox/Devices/Audio/DrvHostDSound.cpp b/src/VBox/Devices/Audio/DrvHostDSound.cpp
index 59b3ffe..d9fc226 100644
--- a/src/VBox/Devices/Audio/DrvHostDSound.cpp
+++ b/src/VBox/Devices/Audio/DrvHostDSound.cpp
@@ -33,6 +33,7 @@
 #include <VBox/log.h>
 
 #define DSLOG(a) do { LogRel2(a); } while(0)
+#define DSLOGF(a) do { LogRel3(a); } while(0)
 #define DSLOGREL(a)                 \
     do {                            \
         static int8_t scLogged = 0; \
@@ -1183,10 +1184,10 @@ static DECLCALLBACK(int) drvHostDSoundPlayOut(PPDMIHOSTAUDIO pInterface, PPDMAUD
 
     pDSoundStrmOut->cbPlayWritePos = (cbPlayWritePos + (cReadTotal << cShift)) % cbBuffer;
 
-    LogFlow(("DSound: PlayOut %RU32 (%RU32 samples) out of %d%s, ds write pos %d -> %d, rc=%Rrc\n",
-             AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cReadTotal), cReadTotal, cbLive,
-             cbLive != AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cReadTotal) ? " !!!": "",
-             cbPlayWritePos, pDSoundStrmOut->cbPlayWritePos, rc));
+    DSLOGF(("DSound: PlayOut %RU32 (%RU32 samples) out of %d%s, ds write pos %d -> %d, rc=%Rrc\n",
+            AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cReadTotal), cReadTotal, cbLive,
+            cbLive != AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cReadTotal) ? " !!!": "",
+            cbPlayWritePos, pDSoundStrmOut->cbPlayWritePos, rc));
 
     if (cReadTotal)
     {
@@ -1362,8 +1363,8 @@ static DECLCALLBACK(int) drvHostDSoundCaptureIn(PPDMIHOSTAUDIO pInterface, PPDMA
         return VINF_SUCCESS;
     }
 
-    LogFlow(("DSound: CaptureIn csMixFree = %u, csReadPos = %d, csCaptureReadPos = %d, csCaptured = %u\n",
-             csMixFree, csReadPos, pDSoundStrmIn->csCaptureReadPos, csCaptured));
+    DSLOGF(("DSound: CaptureIn csMixFree = %u, csReadPos = %d, csCaptureReadPos = %d, csCaptured = %u\n",
+            csMixFree, csReadPos, pDSoundStrmIn->csCaptureReadPos, csCaptured));
 
     /* No need to fetch more samples than mix buffer can receive. */
     csCaptured = RT_MIN(csCaptured, csMixFree);
@@ -1419,8 +1420,8 @@ static DECLCALLBACK(int) drvHostDSoundCaptureIn(PPDMIHOSTAUDIO pInterface, PPDMA
     if (RT_SUCCESS(rc))
     {
         pDSoundStrmIn->csCaptureReadPos = (pDSoundStrmIn->csCaptureReadPos + csProcessed) % pDSoundStrmIn->csCaptureBufferSize;
-        LogFlow(("DSound: CaptureIn %d (%d+%d), processed %d/%d\n",
-                 csCaptured, len1, len2, csProcessed, csWrittenTotal));
+        DSLOGF(("DSound: CaptureIn %d (%d+%d), processed %d/%d\n",
+                csCaptured, len1, len2, csProcessed, csWrittenTotal));
     }
 
     if (pcSamplesCaptured)
@@ -1576,6 +1577,12 @@ static void dSoundConfigInit(PDRVHOSTDSOUND pThis, PCFGMNODE pCfg)
 
     pThis->cfg.pGuidPlay    = dsoundConfigQueryGUID(pCfg, "DeviceGuidOut", &pThis->cfg.uuidPlay);
     pThis->cfg.pGuidCapture = dsoundConfigQueryGUID(pCfg, "DeviceGuidIn",  &pThis->cfg.uuidCapture);
+
+    DSLOG(("DSound: BufsizeOut %u, BufsizeIn %u, DeviceGuidOut {%RTuuid}, DeviceGuidIn {%RTuuid}\n",
+           pThis->cfg.cbBufferOut,
+           pThis->cfg.cbBufferIn,
+           &pThis->cfg.uuidPlay,
+           &pThis->cfg.uuidCapture));
 }
 
 static DECLCALLBACK(void) drvHostDSoundDestruct(PPDMDRVINS pDrvIns)
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyUtility/setup.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyUtility/setup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/AutoGen.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/AutoGen.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/BuildEngine.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/BuildEngine.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenC.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenC.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenDepex.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenDepex.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenMake.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenMake.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/StrGather.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/StrGather.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/UniClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/UniClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/BPDG.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/BPDG.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/GenVpd.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/GenVpd.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/StringTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/StringTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Database.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Database.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DecClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DecClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Dictionary.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Dictionary.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DscClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DscClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspace.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspace.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkLogger.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkLogger.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Expression.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Expression.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/FdfClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/FdfClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/InfClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/InfClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/MigrationUtilities.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/MigrationUtilities.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Misc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Misc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Parsing.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Parsing.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/String.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/String.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/TargetTxtClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/TargetTxtClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/ToolDefClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/ToolDefClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/ModuleClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/ModuleClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PackageClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PackageClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PlatformClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PlatformClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CLexer.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CLexer.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Check.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Check.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CodeFragmentCollector.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CodeFragmentCollector.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Configuration.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Configuration.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Database.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Database.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Ecc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Ecc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Exception.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Exception.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/FileProfile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/FileProfile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaDataParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaDataParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaDataTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaDataTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Xml/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Xml/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/c.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/c.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CLexer.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CLexer.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CodeFragmentCollector.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CodeFragmentCollector.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Database.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Database.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Eot.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Eot.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/EotGlobalData.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/EotGlobalData.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FileProfile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FileProfile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FvImage.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FvImage.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/InfParserLite.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/InfParserLite.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Parser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Parser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/AprioriSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/AprioriSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Capsule.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Capsule.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CapsuleData.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CapsuleData.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/ComponentStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/ComponentStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CompressSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CompressSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DataSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DataSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DepexSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DepexSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/EfiSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/EfiSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fd.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fd.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FdfParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FdfParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Ffs.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Ffs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsFileStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsInfStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fv.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fv.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FvImageSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FvImageSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFds.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFds.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptionRom.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptionRom.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Region.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Region.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Rule.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Rule.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleComplexFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleComplexFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleSimpleFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleSimpleFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Section.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Section.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/UiSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/UiSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/VerSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/VerSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Vtf.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Vtf.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDataModel.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDataModel.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDec.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDec.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDsc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDsc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableEotReport.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableEotReport.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFdf.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFdf.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFunction.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFunction.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableIdentifier.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableIdentifier.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableInf.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableInf.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TablePcd.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TablePcd.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableQuery.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableQuery.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableReport.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableReport.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/TargetTool/TargetTool.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/TargetTool/TargetTool.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Trim/Trim.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Trim/Trim.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/BuildVersion.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/BuildVersion.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DependencyRules.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DependencyRules.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/IpiDb.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/IpiDb.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/PackageFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/PackageFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/InstallPkg.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/InstallPkg.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentGenerating.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentGenerating.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentParsing.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentParsing.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/DataType.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/DataType.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/GlobalData.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/GlobalData.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Misc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Misc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ParserValidate.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ParserValidate.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Parsing.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Parsing.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/String.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/String.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/Log.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/Log.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/StringTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/StringTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/MkPkg.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/MkPkg.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/DecObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/DecObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/CommonXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/CommonXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/IniToXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/IniToXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PcdXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PcdXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/BuildClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/BuildClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaDataTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaDataTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/BuildReport.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/BuildReport.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/build.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/build.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
index 9c1178a..6fdf3b1 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd differ
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
index be17d03..a0686f4 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd differ
diff --git a/src/VBox/Devices/Graphics/BIOS/Makefile.kmk b/src/VBox/Devices/Graphics/BIOS/Makefile.kmk
index 35f4255..9a5d677 100644
--- a/src/VBox/Devices/Graphics/BIOS/Makefile.kmk
+++ b/src/VBox/Devices/Graphics/BIOS/Makefile.kmk
@@ -39,9 +39,9 @@ ifdef VBOX_WITH_OPEN_WATCOM
  	 clname CODE  \
 	  segment VGAROM segaddr=0xC000 \
  	  segment _TEXT  segaddr=0xC000 offset=0xA00 \
- 	  segment VBE32  segaddr=0xC000 offset=0x4600 \
+ 	  segment VBE32  segaddr=0xC000 offset=0x4400 \
  	 clname DATA \
- 	  segment _DATA  segaddr=0xC000 offset=0x4800 \
+ 	  segment _DATA  segaddr=0xC000 offset=0x4600 \
 
  #
  # Updates the alternative source file.
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
index e2dede7..3f9ae24 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
@@ -164,11 +164,11 @@
 
 
 
-section VGAROM progbits vstart=0x0 align=1 ; size=0x93e class=CODE group=AUTO
+section VGAROM progbits vstart=0x0 align=1 ; size=0x994 class=CODE group=AUTO
     db  055h, 0aah, 040h, 0e9h, 062h, 00ah, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 049h, 042h
     db  04dh, 000h
-vgabios_int10_handler:                       ; 0xc0022 LB 0x585
+vgabios_int10_handler:                       ; 0xc0022 LB 0x54e
     pushfw                                    ; 9c
     cmp ah, 00fh                              ; 80 fc 0f
     jne short 0002eh                          ; 75 06
@@ -222,31 +222,31 @@ vgabios_int10_handler:                       ; 0xc0022 LB 0x585
     jne short 000e5h                          ; 75 3f
     cmp AL, strict byte 003h                  ; 3c 03
     jne short 000afh                          ; 75 05
-    call 007b7h                               ; e8 0a 07
+    call 0080dh                               ; e8 60 07
     jmp short 000f3h                          ; eb 44
     cmp AL, strict byte 005h                  ; 3c 05
     jne short 000b8h                          ; 75 05
-    call 007dch                               ; e8 26 07
+    call 00832h                               ; e8 7c 07
     jmp short 000f3h                          ; eb 3b
     cmp AL, strict byte 006h                  ; 3c 06
     jne short 000c1h                          ; 75 05
-    call 00809h                               ; e8 4a 07
+    call 0085fh                               ; e8 a0 07
     jmp short 000f3h                          ; eb 32
     cmp AL, strict byte 007h                  ; 3c 07
     jne short 000cah                          ; 75 05
-    call 00856h                               ; e8 8e 07
+    call 008ach                               ; e8 e4 07
     jmp short 000f3h                          ; eb 29
     cmp AL, strict byte 008h                  ; 3c 08
     jne short 000d3h                          ; 75 05
-    call 0088ah                               ; e8 b9 07
+    call 008e0h                               ; e8 0f 08
     jmp short 000f3h                          ; eb 20
     cmp AL, strict byte 009h                  ; 3c 09
     jne short 000dch                          ; 75 05
-    call 008c1h                               ; e8 e7 07
+    call 00917h                               ; e8 3d 08
     jmp short 000f3h                          ; eb 17
     cmp AL, strict byte 00ah                  ; 3c 0a
     jne short 000e5h                          ; 75 05
-    call 00925h                               ; e8 42 08
+    call 0097bh                               ; e8 98 08
     jmp short 000f3h                          ; eb 0e
     push ES                                   ; 06
     push DS                                   ; 1e
@@ -947,13 +947,24 @@ vgabios_int10_handler:                       ; 0xc0022 LB 0x585
     ; mov al, ah                                ; 8a c4
     pop DS                                    ; 1f
     retn                                      ; c3
-    add byte [bx+si], al                      ; 00 00
-    add byte [bx+si], al                      ; 00 00
-    add byte [bx+si+052h], dl                 ; 00 50 52
+    times 0x5 db 0
+do_out_dx_ax:                                ; 0xc0570 LB 0x7
+    xchg ah, al                               ; 86 c4
+    out DX, AL                                ; ee
+    xchg ah, al                               ; 86 c4
+    out DX, AL                                ; ee
+    retn                                      ; c3
+do_in_ax_dx:                                 ; 0xc0577 LB 0x40
+    in AL, DX                                 ; ec
+    xchg ah, al                               ; 86 c4
+    in AL, DX                                 ; ec
+    retn                                      ; c3
+    push ax                                   ; 50
+    push dx                                   ; 52
     mov dx, 003dah                            ; ba da 03
     in AL, DX                                 ; ec
     test AL, strict byte 008h                 ; a8 08
-    je short 00575h                           ; 74 fb
+    je short 00581h                           ; 74 fb
     pop dx                                    ; 5a
     pop ax                                    ; 58
     retn                                      ; c3
@@ -962,114 +973,114 @@ vgabios_int10_handler:                       ; 0xc0022 LB 0x585
     mov dx, 003dah                            ; ba da 03
     in AL, DX                                 ; ec
     test AL, strict byte 008h                 ; a8 08
-    jne short 00582h                          ; 75 fb
+    jne short 0058eh                          ; 75 fb
     pop dx                                    ; 5a
     pop ax                                    ; 58
     retn                                      ; c3
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00003h                ; b8 03 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 d0 ff
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 d1 ff
     cmp AL, strict byte 004h                  ; 3c 04
-    jbe short 005a5h                          ; 76 0b
+    jbe short 005b5h                          ; 76 0b
     db  08ah, 0e0h
     ; mov ah, al                                ; 8a e0
     shr ah, 003h                              ; c0 ec 03
     test AL, strict byte 007h                 ; a8 07
-    je short 005a5h                           ; 74 02
+    je short 005b5h                           ; 74 02
     db  0feh, 0c4h
     ; inc ah                                    ; fe c4
     pop dx                                    ; 5a
     retn                                      ; c3
-_dispi_get_max_bpp:                          ; 0xc05a7 LB 0x22
+_dispi_get_max_bpp:                          ; 0xc05b7 LB 0x26
     push dx                                   ; 52
     push bx                                   ; 53
-    call 005d9h                               ; e8 2d 00
+    call 005f1h                               ; e8 35 00
     db  08bh, 0d8h
     ; mov bx, ax                                ; 8b d8
     or ax, strict byte 00002h                 ; 83 c8 02
-    call 005c9h                               ; e8 15 00
+    call 005ddh                               ; e8 19 00
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00003h                ; b8 03 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 a3 ff
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 a4 ff
     push ax                                   ; 50
     db  08bh, 0c3h
     ; mov ax, bx                                ; 8b c3
-    call 005c9h                               ; e8 04 00
+    call 005ddh                               ; e8 04 00
     pop ax                                    ; 58
     pop bx                                    ; 5b
     pop dx                                    ; 5a
     retn                                      ; c3
-dispi_set_enable_:                           ; 0xc05c9 LB 0x1e
+dispi_set_enable_:                           ; 0xc05dd LB 0x26
     push dx                                   ; 52
     push ax                                   ; 50
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00004h                ; b8 04 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 88 ff
     pop ax                                    ; 58
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 81 ff
     pop dx                                    ; 5a
     retn                                      ; c3
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00004h                ; b8 04 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 75 ff
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 76 ff
     pop dx                                    ; 5a
     retn                                      ; c3
-dispi_set_bank_:                             ; 0xc05e7 LB 0x1e
+dispi_set_bank_:                             ; 0xc0603 LB 0x26
     push dx                                   ; 52
     push ax                                   ; 50
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00005h                ; b8 05 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 62 ff
     pop ax                                    ; 58
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 5b ff
     pop dx                                    ; 5a
     retn                                      ; c3
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00005h                ; b8 05 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 4f ff
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 50 ff
     pop dx                                    ; 5a
     retn                                      ; c3
-_dispi_set_bank_farcall:                     ; 0xc0605 LB 0xbe
+_dispi_set_bank_farcall:                     ; 0xc0629 LB 0xe4
     cmp bx, 00100h                            ; 81 fb 00 01
-    je short 00629h                           ; 74 1e
+    je short 00653h                           ; 74 24
     db  00bh, 0dbh
     ; or bx, bx                                 ; 0b db
-    jne short 00637h                          ; 75 28
+    jne short 00665h                          ; 75 32
     db  08bh, 0c2h
     ; mov ax, dx                                ; 8b c2
     push dx                                   ; 52
     push ax                                   ; 50
     mov ax, strict word 00005h                ; b8 05 00
     mov dx, 001ceh                            ; ba ce 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 30 ff
     pop ax                                    ; 58
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
-    in ax, DX                                 ; ed
+    call 00570h                               ; e8 29 ff
+    call 00577h                               ; e8 2d ff
     pop dx                                    ; 5a
     db  03bh, 0d0h
     ; cmp dx, ax                                ; 3b d0
-    jne short 00637h                          ; 75 12
+    jne short 00665h                          ; 75 16
     mov ax, strict word 0004fh                ; b8 4f 00
     retf                                      ; cb
     mov ax, strict word 00005h                ; b8 05 00
     mov dx, 001ceh                            ; ba ce 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 14 ff
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 15 ff
     db  08bh, 0d0h
     ; mov dx, ax                                ; 8b d0
     retf                                      ; cb
@@ -1079,36 +1090,36 @@ _dispi_set_bank_farcall:                     ; 0xc0605 LB 0xbe
     push ax                                   ; 50
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00008h                ; b8 08 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 fc fe
     pop ax                                    ; 58
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 f5 fe
     pop dx                                    ; 5a
     retn                                      ; c3
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00008h                ; b8 08 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 e9 fe
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 ea fe
     pop dx                                    ; 5a
     retn                                      ; c3
     push dx                                   ; 52
     push ax                                   ; 50
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00009h                ; b8 09 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 d6 fe
     pop ax                                    ; 58
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 cf fe
     pop dx                                    ; 5a
     retn                                      ; c3
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00009h                ; b8 09 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 c3 fe
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 c4 fe
     pop dx                                    ; 5a
     retn                                      ; c3
     push ax                                   ; 50
@@ -1116,9 +1127,9 @@ _dispi_set_bank_farcall:                     ; 0xc0605 LB 0xbe
     push dx                                   ; 52
     db  08bh, 0d8h
     ; mov bx, ax                                ; 8b d8
-    call 0058ah                               ; e8 0b ff
+    call 00596h                               ; e8 d9 fe
     cmp AL, strict byte 004h                  ; 3c 04
-    jnbe short 00685h                         ; 77 02
+    jnbe short 006c3h                         ; 77 02
     shr bx, 1                                 ; d1 eb
     shr bx, 003h                              ; c1 eb 03
     mov dx, 003d4h                            ; ba d4 03
@@ -1130,41 +1141,41 @@ _dispi_set_bank_farcall:                     ; 0xc0605 LB 0xbe
     pop bx                                    ; 5b
     pop ax                                    ; 58
     retn                                      ; c3
-    call 00677h                               ; e8 e0 ff
+    call 006b5h                               ; e8 e0 ff
     push dx                                   ; 52
     push ax                                   ; 50
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00006h                ; b8 06 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 90 fe
     pop ax                                    ; 58
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 89 fe
     pop dx                                    ; 5a
     retn                                      ; c3
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00006h                ; b8 06 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 7d fe
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 7e fe
     pop dx                                    ; 5a
     retn                                      ; c3
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00007h                ; b8 07 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 6b fe
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 6c fe
     pop dx                                    ; 5a
     retn                                      ; c3
-_vga_compat_setup:                           ; 0xc06c3 LB 0xe1
+_vga_compat_setup:                           ; 0xc070d LB 0xed
     push ax                                   ; 50
     push dx                                   ; 52
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00001h                ; b8 01 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 58 fe
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 59 fe
     push ax                                   ; 50
     mov dx, 003d4h                            ; ba d4 03
     mov ax, strict word 00011h                ; b8 11 00
@@ -1178,12 +1189,12 @@ _vga_compat_setup:                           ; 0xc06c3 LB 0xe1
     mov AL, strict byte 001h                  ; b0 01
     out DX, ax                                ; ef
     pop ax                                    ; 58
-    call 00677h                               ; e8 90 ff
+    call 006b5h                               ; e8 80 ff
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00002h                ; b8 02 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 32 fe
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 33 fe
     dec ax                                    ; 48
     push ax                                   ; 50
     mov dx, 003d4h                            ; ba d4 03
@@ -1198,10 +1209,10 @@ _vga_compat_setup:                           ; 0xc06c3 LB 0xe1
     in AL, DX                                 ; ec
     and AL, strict byte 0bdh                  ; 24 bd
     test ah, 001h                             ; f6 c4 01
-    je short 0070bh                           ; 74 02
+    je short 0075dh                           ; 74 02
     or AL, strict byte 002h                   ; 0c 02
     test ah, 002h                             ; f6 c4 02
-    je short 00712h                           ; 74 02
+    je short 00764h                           ; 74 02
     or AL, strict byte 040h                   ; 0c 40
     out DX, AL                                ; ee
     mov dx, 003d4h                            ; ba d4 03
@@ -1238,11 +1249,11 @@ _vga_compat_setup:                           ; 0xc06c3 LB 0xe1
     out DX, ax                                ; ef
     mov dx, 001ceh                            ; ba ce 01
     mov ax, strict word 00003h                ; b8 03 00
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 c2 fd
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 c3 fd
     cmp AL, strict byte 008h                  ; 3c 08
-    jc short 007a2h                           ; 72 40
+    jc short 007f8h                           ; 72 40
     mov dx, 003d4h                            ; ba d4 03
     mov AL, strict byte 014h                  ; b0 14
     out DX, AL                                ; ee
@@ -1279,7 +1290,7 @@ _vga_compat_setup:                           ; 0xc06c3 LB 0xe1
     out DX, AL                                ; ee
     pop dx                                    ; 5a
     pop ax                                    ; 58
-_vbe_has_vbe_display:                        ; 0xc07a4 LB 0x13
+_vbe_has_vbe_display:                        ; 0xc07fa LB 0x13
     push DS                                   ; 1e
     push bx                                   ; 53
     mov ax, strict word 00040h                ; b8 40 00
@@ -1292,18 +1303,18 @@ _vbe_has_vbe_display:                        ; 0xc07a4 LB 0x13
     pop bx                                    ; 5b
     pop DS                                    ; 1f
     retn                                      ; c3
-vbe_biosfn_return_current_mode:              ; 0xc07b7 LB 0x25
+vbe_biosfn_return_current_mode:              ; 0xc080d LB 0x25
     push DS                                   ; 1e
     mov ax, strict word 00040h                ; b8 40 00
     mov ds, ax                                ; 8e d8
-    call 005d9h                               ; e8 19 fe
+    call 005f1h                               ; e8 db fd
     and ax, strict byte 00001h                ; 83 e0 01
-    je short 007ceh                           ; 74 09
+    je short 00824h                           ; 74 09
     mov bx, 000bah                            ; bb ba 00
     mov ax, word [bx]                         ; 8b 07
     db  08bh, 0d8h
     ; mov bx, ax                                ; 8b d8
-    jne short 007d7h                          ; 75 09
+    jne short 0082dh                          ; 75 09
     mov bx, strict word 00049h                ; bb 49 00
     mov al, byte [bx]                         ; 8a 07
     db  08ah, 0d8h
@@ -1313,138 +1324,138 @@ vbe_biosfn_return_current_mode:              ; 0xc07b7 LB 0x25
     mov ax, strict word 0004fh                ; b8 4f 00
     pop DS                                    ; 1f
     retn                                      ; c3
-vbe_biosfn_display_window_control:           ; 0xc07dc LB 0x2d
+vbe_biosfn_display_window_control:           ; 0xc0832 LB 0x2d
     cmp bl, 000h                              ; 80 fb 00
-    jne short 00805h                          ; 75 24
+    jne short 0085bh                          ; 75 24
     cmp bh, 001h                              ; 80 ff 01
-    je short 007fch                           ; 74 16
-    jc short 007ech                           ; 72 04
+    je short 00852h                           ; 74 16
+    jc short 00842h                           ; 72 04
     mov ax, 00100h                            ; b8 00 01
     retn                                      ; c3
     db  08bh, 0c2h
     ; mov ax, dx                                ; 8b c2
-    call 005e7h                               ; e8 f6 fd
-    call 005f7h                               ; e8 03 fe
+    call 00603h                               ; e8 bc fd
+    call 00617h                               ; e8 cd fd
     db  03bh, 0c2h
     ; cmp ax, dx                                ; 3b c2
-    jne short 00805h                          ; 75 0d
+    jne short 0085bh                          ; 75 0d
     mov ax, strict word 0004fh                ; b8 4f 00
     retn                                      ; c3
-    call 005f7h                               ; e8 f8 fd
+    call 00617h                               ; e8 c2 fd
     db  08bh, 0d0h
     ; mov dx, ax                                ; 8b d0
     mov ax, strict word 0004fh                ; b8 4f 00
     retn                                      ; c3
     mov ax, 0014fh                            ; b8 4f 01
     retn                                      ; c3
-vbe_biosfn_set_get_logical_scan_line_length: ; 0xc0809 LB 0x4d
+vbe_biosfn_set_get_logical_scan_line_length: ; 0xc085f LB 0x4d
     db  08bh, 0c1h
     ; mov ax, cx                                ; 8b c1
     cmp bl, 001h                              ; 80 fb 01
-    je short 00834h                           ; 74 24
+    je short 0088ah                           ; 74 24
     cmp bl, 002h                              ; 80 fb 02
-    je short 0081bh                           ; 74 06
-    jc short 00831h                           ; 72 1a
+    je short 00871h                           ; 74 06
+    jc short 00887h                           ; 72 1a
     mov ax, 00100h                            ; b8 00 01
     retn                                      ; c3
     push ax                                   ; 50
-    call 0058ah                               ; e8 6b fd
+    call 00596h                               ; e8 21 fd
     db  032h, 0ffh
     ; xor bh, bh                                ; 32 ff
     db  08ah, 0dch
     ; mov bl, ah                                ; 8a dc
     db  00ah, 0dbh
     ; or bl, bl                                 ; 0a db
-    jne short 0082ch                          ; 75 05
+    jne short 00882h                          ; 75 05
     sal ax, 003h                              ; c1 e0 03
     mov BL, strict byte 001h                  ; b3 01
     db  033h, 0d2h
     ; xor dx, dx                                ; 33 d2
     pop ax                                    ; 58
     div bx                                    ; f7 f3
-    call 00694h                               ; e8 60 fe
-    call 0058ah                               ; e8 53 fd
+    call 006d2h                               ; e8 48 fe
+    call 00596h                               ; e8 09 fd
     db  032h, 0ffh
     ; xor bh, bh                                ; 32 ff
     db  08ah, 0dch
     ; mov bl, ah                                ; 8a dc
-    call 006a7h                               ; e8 69 fe
+    call 006e9h                               ; e8 55 fe
     db  08bh, 0c8h
     ; mov cx, ax                                ; 8b c8
     db  00ah, 0dbh
     ; or bl, bl                                 ; 0a db
-    jne short 00849h                          ; 75 05
+    jne short 0089fh                          ; 75 05
     shr ax, 003h                              ; c1 e8 03
     mov BL, strict byte 001h                  ; b3 01
     mul bx                                    ; f7 e3
     db  08bh, 0d8h
     ; mov bx, ax                                ; 8b d8
-    call 006b5h                               ; e8 65 fe
+    call 006fbh                               ; e8 55 fe
     db  08bh, 0d0h
     ; mov dx, ax                                ; 8b d0
     mov ax, strict word 0004fh                ; b8 4f 00
     retn                                      ; c3
-vbe_biosfn_set_get_display_start:            ; 0xc0856 LB 0x34
+vbe_biosfn_set_get_display_start:            ; 0xc08ac LB 0x34
     cmp bl, 080h                              ; 80 fb 80
-    je short 00866h                           ; 74 0b
+    je short 008bch                           ; 74 0b
     cmp bl, 001h                              ; 80 fb 01
-    je short 0087ah                           ; 74 1a
-    jc short 0086ch                           ; 72 0a
+    je short 008d0h                           ; 74 1a
+    jc short 008c2h                           ; 72 0a
     mov ax, 00100h                            ; b8 00 01
     retn                                      ; c3
-    call 0057dh                               ; e8 14 fd
-    call 00570h                               ; e8 04 fd
+    call 00589h                               ; e8 ca fc
+    call 0057ch                               ; e8 ba fc
     db  08bh, 0c1h
     ; mov ax, cx                                ; 8b c1
-    call 0063bh                               ; e8 ca fd
+    call 00669h                               ; e8 a2 fd
     db  08bh, 0c2h
     ; mov ax, dx                                ; 8b c2
-    call 00659h                               ; e8 e3 fd
+    call 0068fh                               ; e8 c3 fd
     mov ax, strict word 0004fh                ; b8 4f 00
     retn                                      ; c3
-    call 0064bh                               ; e8 ce fd
+    call 0067dh                               ; e8 aa fd
     db  08bh, 0c8h
     ; mov cx, ax                                ; 8b c8
-    call 00669h                               ; e8 e7 fd
+    call 006a3h                               ; e8 cb fd
     db  08bh, 0d0h
     ; mov dx, ax                                ; 8b d0
     db  032h, 0ffh
     ; xor bh, bh                                ; 32 ff
     mov ax, strict word 0004fh                ; b8 4f 00
     retn                                      ; c3
-vbe_biosfn_set_get_dac_palette_format:       ; 0xc088a LB 0x37
+vbe_biosfn_set_get_dac_palette_format:       ; 0xc08e0 LB 0x37
     cmp bl, 001h                              ; 80 fb 01
-    je short 008adh                           ; 74 1e
-    jc short 00895h                           ; 72 04
+    je short 00903h                           ; 74 1e
+    jc short 008ebh                           ; 72 04
     mov ax, 00100h                            ; b8 00 01
     retn                                      ; c3
-    call 005d9h                               ; e8 41 fd
+    call 005f1h                               ; e8 03 fd
     cmp bh, 006h                              ; 80 ff 06
-    je short 008a7h                           ; 74 0a
+    je short 008fdh                           ; 74 0a
     cmp bh, 008h                              ; 80 ff 08
-    jne short 008bdh                          ; 75 1b
+    jne short 00913h                          ; 75 1b
     or ax, strict byte 00020h                 ; 83 c8 20
-    jne short 008aah                          ; 75 03
+    jne short 00900h                          ; 75 03
     and ax, strict byte 0ffdfh                ; 83 e0 df
-    call 005c9h                               ; e8 1c fd
+    call 005ddh                               ; e8 da fc
     mov BH, strict byte 006h                  ; b7 06
-    call 005d9h                               ; e8 27 fd
+    call 005f1h                               ; e8 e9 fc
     and ax, strict byte 00020h                ; 83 e0 20
-    je short 008b9h                           ; 74 02
+    je short 0090fh                           ; 74 02
     mov BH, strict byte 008h                  ; b7 08
     mov ax, strict word 0004fh                ; b8 4f 00
     retn                                      ; c3
     mov ax, 0014fh                            ; b8 4f 01
     retn                                      ; c3
-vbe_biosfn_set_get_palette_data:             ; 0xc08c1 LB 0x64
+vbe_biosfn_set_get_palette_data:             ; 0xc0917 LB 0x64
     test bl, bl                               ; 84 db
-    je short 008d4h                           ; 74 0f
+    je short 0092ah                           ; 74 0f
     cmp bl, 001h                              ; 80 fb 01
-    je short 008fch                           ; 74 32
+    je short 00952h                           ; 74 32
     cmp bl, 003h                              ; 80 fb 03
-    jbe short 00921h                          ; 76 52
+    jbe short 00977h                          ; 76 52
     cmp bl, 080h                              ; 80 fb 80
-    jne short 0091dh                          ; 75 49
+    jne short 00973h                          ; 75 49
     pushad                                    ; 66 60
     push DS                                   ; 1e
     push ES                                   ; 06
@@ -1463,7 +1474,7 @@ vbe_biosfn_set_get_palette_data:             ; 0xc08c1 LB 0x64
     out DX, AL                                ; ee
     rol eax, 008h                             ; 66 c1 c0 08
     out DX, AL                                ; ee
-    loop 008e2h                               ; e2 ed
+    loop 00938h                               ; e2 ed
     pop DS                                    ; 1f
     popad                                     ; 66 61
     mov ax, strict word 0004fh                ; b8 4f 00
@@ -1482,19 +1493,19 @@ vbe_biosfn_set_get_palette_data:             ; 0xc08c1 LB 0x64
     sal eax, 008h                             ; 66 c1 e0 08
     in AL, DX                                 ; ec
     stosd                                     ; 66 ab
-    loop 00907h                               ; e2 ee
+    loop 0095dh                               ; e2 ee
     popad                                     ; 66 61
-    jmp short 008f8h                          ; eb db
+    jmp short 0094eh                          ; eb db
     mov ax, 0014fh                            ; b8 4f 01
     retn                                      ; c3
     mov ax, 0024fh                            ; b8 4f 02
     retn                                      ; c3
-vbe_biosfn_return_protected_mode_interface: ; 0xc0925 LB 0x19
+vbe_biosfn_return_protected_mode_interface: ; 0xc097b LB 0x19
     test bl, bl                               ; 84 db
-    jne short 0093ah                          ; 75 11
+    jne short 00990h                          ; 75 11
     mov di, 0c000h                            ; bf 00 c0
     mov es, di                                ; 8e c7
-    mov di, 04600h                            ; bf 00 46
+    mov di, 04400h                            ; bf 00 44
     mov cx, 00115h                            ; b9 15 01
     db  02bh, 0cfh
     ; sub cx, di                                ; 2b cf
@@ -1503,10 +1514,10 @@ vbe_biosfn_return_protected_mode_interface: ; 0xc0925 LB 0x19
     mov ax, 0014fh                            ; b8 4f 01
     retn                                      ; c3
 
-  ; Padding 0xc2 bytes at 0xc093e
-  times 194 db 0
+  ; Padding 0x6c bytes at 0xc0994
+  times 108 db 0
 
-section _TEXT progbits vstart=0xa00 align=1 ; size=0x2f47 class=CODE group=AUTO
+section _TEXT progbits vstart=0xa00 align=1 ; size=0x2f57 class=CODE group=AUTO
 set_int_vector_:                             ; 0xc0a00 LB 0x1a
     push bx                                   ; 53
     push bp                                   ; 55
@@ -1560,7 +1571,7 @@ _vgabios_init_func:                          ; 0xc0a68 LB 0x20
     mov bp, sp                                ; 89 e5
     call 00a1ah                               ; e8 ac ff
     call 00a36h                               ; e8 c5 ff
-    call 03476h                               ; e8 02 2a
+    call 03482h                               ; e8 0e 2a
     mov dx, strict word 00022h                ; ba 22 00
     mov ax, strict word 00010h                ; b8 10 00
     call 00a00h                               ; e8 83 ff
@@ -1642,7 +1653,7 @@ vga_read_char_attr_:                         ; 0xc0acb LB 0xa8
     call 02f5ah                               ; e8 3a 24
     movzx bx, ch                              ; 0f b6 dd
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
+    cmp byte [bx+04635h], 000h                ; 80 bf 35 46 00
     jne short 00b5ah                          ; 75 2d
     mov dx, ax                                ; 89 c2
     imul dx, di                               ; 0f af d7
@@ -1658,7 +1669,7 @@ vga_read_char_attr_:                         ; 0xc0acb LB 0xa8
     add ax, ax                                ; 01 c0
     mov dx, cx                                ; 89 ca
     add dx, ax                                ; 01 c2
-    mov ax, word [bx+04833h]                  ; 8b 87 33 48
+    mov ax, word [bx+04638h]                  ; 8b 87 38 46
     call 02f5ah                               ; e8 03 24
     mov word [ss:si], ax                      ; 36 89 04
     lea sp, [bp-008h]                         ; 8d 66 f8
@@ -1724,18 +1735,18 @@ vga_get_font_info_:                          ; 0xc0b73 LB 0x82
     retn 00002h                               ; c2 02 00
     mov dx, 0010ch                            ; ba 0c 01
     jmp short 00b91h                          ; eb bf
-    mov ax, 05dafh                            ; b8 af 5d
+    mov ax, 05bf2h                            ; b8 f2 5b
     mov dx, 0c000h                            ; ba 00 c0
     jmp short 00b96h                          ; eb bc
-    mov ax, 055afh                            ; b8 af 55
+    mov ax, 053f2h                            ; b8 f2 53
     jmp short 00bd5h                          ; eb f6
-    mov ax, 059afh                            ; b8 af 59
+    mov ax, 057f2h                            ; b8 f2 57
     jmp short 00bd5h                          ; eb f1
-    mov ax, 07bafh                            ; b8 af 7b
+    mov ax, 079f2h                            ; b8 f2 79
     jmp short 00bd5h                          ; eb ec
-    mov ax, 06bafh                            ; b8 af 6b
+    mov ax, 069f2h                            ; b8 f2 69
     jmp short 00bd5h                          ; eb e7
-    mov ax, 07cdch                            ; b8 dc 7c
+    mov ax, 07b1fh                            ; b8 1f 7b
     jmp short 00bd5h                          ; eb e2
     jmp short 00bc4h                          ; eb cf
 vga_read_pixel_:                             ; 0xc0bf5 LB 0x139
@@ -1757,9 +1768,9 @@ vga_read_pixel_:                             ; 0xc0bf5 LB 0x139
     je near 00d27h                            ; 0f 84 0d 01
     movzx bx, al                              ; 0f b6 d8
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
+    cmp byte [bx+04635h], 000h                ; 80 bf 35 46 00
     je near 00d27h                            ; 0f 84 fe 00
-    mov bl, byte [bx+04831h]                  ; 8a 9f 31 48
+    mov bl, byte [bx+04636h]                  ; 8a 9f 36 46
     cmp bl, 003h                              ; 80 fb 03
     jc short 00c43h                           ; 72 11
     jbe short 00c4bh                          ; 76 17
@@ -1818,7 +1829,7 @@ vga_read_pixel_:                             ; 0xc0bf5 LB 0x139
     call 02f3eh                               ; e8 7b 22
     movzx bx, cl                              ; 0f b6 d9
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04832h], 002h                ; 80 bf 32 48 02
+    cmp byte [bx+04637h], 002h                ; 80 bf 37 46 02
     jne short 00cebh                          ; 75 1b
     mov cx, si                                ; 89 f1
     xor ch, ch                                ; 30 ed
@@ -2119,7 +2130,7 @@ biosfn_set_active_page_:                     ; 0xc0f00 LB 0xdc
     movzx bx, ch                              ; 0f b6 dd
     mov si, bx                                ; 89 de
     sal si, 003h                              ; c1 e6 03
-    cmp byte [si+04830h], 000h                ; 80 bc 30 48 00
+    cmp byte [si+04635h], 000h                ; 80 bc 35 46 00
     jne short 00f83h                          ; 75 40
     mov dx, strict word 0004ah                ; ba 4a 00
     mov ax, strict word 00040h                ; b8 40 00
@@ -2146,10 +2157,10 @@ biosfn_set_active_page_:                     ; 0xc0f00 LB 0xdc
     lea bx, [si+001h]                         ; 8d 5c 01
     imul bx, di                               ; 0f af df
     jmp short 00f95h                          ; eb 12
-    movzx bx, byte [bx+048afh]                ; 0f b6 9f af 48
+    movzx bx, byte [bx+046b4h]                ; 0f b6 9f b4 46
     sal bx, 006h                              ; c1 e3 06
     movzx ax, cl                              ; 0f b6 c1
-    mov bx, word [bx+048c6h]                  ; 8b 9f c6 48
+    mov bx, word [bx+046cbh]                  ; 8b 9f cb 46
     imul bx, ax                               ; 0f af d8
     mov dx, strict word 00063h                ; ba 63 00
     mov ax, strict word 00040h                ; b8 40 00
@@ -2198,7 +2209,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     mov byte [bp-00ch], al                    ; 88 46 f4
     and AL, strict byte 080h                  ; 24 80
     mov byte [bp-010h], al                    ; 88 46 f0
-    call 007a4h                               ; e8 b2 f7
+    call 007fah                               ; e8 08 f8
     test ax, ax                               ; 85 c0
     je short 01002h                           ; 74 0c
     mov AL, strict byte 007h                  ; b0 07
@@ -2217,15 +2228,15 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     cmp AL, strict byte 0ffh                  ; 3c ff
     je near 01363h                            ; 0f 84 43 03
     movzx si, al                              ; 0f b6 f0
-    mov al, byte [si+048afh]                  ; 8a 84 af 48
+    mov al, byte [si+046b4h]                  ; 8a 84 b4 46
     mov byte [bp-00eh], al                    ; 88 46 f2
     movzx bx, al                              ; 0f b6 d8
     sal bx, 006h                              ; c1 e3 06
-    movzx ax, byte [bx+048c3h]                ; 0f b6 87 c3 48
+    movzx ax, byte [bx+046c8h]                ; 0f b6 87 c8 46
     mov word [bp-018h], ax                    ; 89 46 e8
-    movzx ax, byte [bx+048c4h]                ; 0f b6 87 c4 48
+    movzx ax, byte [bx+046c9h]                ; 0f b6 87 c9 46
     mov word [bp-016h], ax                    ; 89 46 ea
-    movzx ax, byte [bx+048c5h]                ; 0f b6 87 c5 48
+    movzx ax, byte [bx+046cah]                ; 0f b6 87 ca 46
     mov word [bp-014h], ax                    ; 89 46 ec
     mov dx, 00087h                            ; ba 87 00
     mov ax, strict word 00040h                ; b8 40 00
@@ -2241,13 +2252,13 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     jne near 010f5h                           ; 0f 85 8a 00
     mov bx, si                                ; 89 f3
     sal bx, 003h                              ; c1 e3 03
-    mov al, byte [bx+04835h]                  ; 8a 87 35 48
+    mov al, byte [bx+0463ah]                  ; 8a 87 3a 46
     mov dx, 003c6h                            ; ba c6 03
     out DX, AL                                ; ee
     xor al, al                                ; 30 c0
     mov dx, 003c8h                            ; ba c8 03
     out DX, AL                                ; ee
-    mov bl, byte [bx+04836h]                  ; 8a 9f 36 48
+    mov bl, byte [bx+0463bh]                  ; 8a 9f 3b 46
     cmp bl, 001h                              ; 80 fb 01
     jc short 01095h                           ; 72 0e
     jbe short 0109eh                          ; 76 15
@@ -2258,13 +2269,13 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     jmp short 010abh                          ; eb 16
     test bl, bl                               ; 84 db
     jne short 010abh                          ; 75 12
-    mov di, 05043h                            ; bf 43 50
+    mov di, 04e48h                            ; bf 48 4e
     jmp short 010abh                          ; eb 0d
-    mov di, 05103h                            ; bf 03 51
+    mov di, 04f08h                            ; bf 08 4f
     jmp short 010abh                          ; eb 08
-    mov di, 051c3h                            ; bf c3 51
+    mov di, 04fc8h                            ; bf c8 4f
     jmp short 010abh                          ; eb 03
-    mov di, 05283h                            ; bf 83 52
+    mov di, 05088h                            ; bf 88 50
     xor bx, bx                                ; 31 db
     jmp short 010beh                          ; eb 0f
     xor al, al                                ; 30 c0
@@ -2277,8 +2288,8 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     jnc short 010e8h                          ; 73 2a
     movzx si, byte [bp-012h]                  ; 0f b6 76 ee
     sal si, 003h                              ; c1 e6 03
-    movzx si, byte [si+04836h]                ; 0f b6 b4 36 48
-    movzx dx, byte [si+048bfh]                ; 0f b6 94 bf 48
+    movzx si, byte [si+0463bh]                ; 0f b6 b4 3b 46
+    movzx dx, byte [si+046c4h]                ; 0f b6 94 c4 46
     cmp bx, dx                                ; 39 d3
     jnbe short 010afh                         ; 77 dc
     imul si, bx, strict byte 00003h           ; 6b f3 03
@@ -2310,7 +2321,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 006h                              ; c1 e6 06
     add si, bx                                ; 01 de
-    mov al, byte [si+048e6h]                  ; 8a 84 e6 48
+    mov al, byte [si+046ebh]                  ; 8a 84 eb 46
     out DX, AL                                ; ee
     inc bx                                    ; 43
     jmp short 010ffh                          ; eb e4
@@ -2334,7 +2345,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 006h                              ; c1 e6 06
     add si, bx                                ; 01 de
-    mov al, byte [si+048c7h]                  ; 8a 84 c7 48
+    mov al, byte [si+046cch]                  ; 8a 84 cc 46
     mov dx, 003c5h                            ; ba c5 03
     out DX, AL                                ; ee
     inc bx                                    ; 43
@@ -2349,14 +2360,14 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 006h                              ; c1 e6 06
     add si, bx                                ; 01 de
-    mov al, byte [si+048fah]                  ; 8a 84 fa 48
+    mov al, byte [si+046ffh]                  ; 8a 84 ff 46
     mov dx, 003cfh                            ; ba cf 03
     out DX, AL                                ; ee
     inc bx                                    ; 43
     jmp short 01156h                          ; eb e1
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04831h], 001h                ; 80 bf 31 48 01
+    cmp byte [bx+04636h], 001h                ; 80 bf 36 46 01
     jne short 01188h                          ; 75 05
     mov dx, 003b4h                            ; ba b4 03
     jmp short 0118bh                          ; eb 03
@@ -2376,12 +2387,12 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     mov di, cx                                ; 89 cf
     add di, bx                                ; 01 df
     lea dx, [si+001h]                         ; 8d 54 01
-    mov al, byte [di+048cdh]                  ; 8a 85 cd 48
+    mov al, byte [di+046d2h]                  ; 8a 85 d2 46
     out DX, AL                                ; ee
     inc bx                                    ; 43
     jmp short 01195h                          ; eb e0
     mov bx, cx                                ; 89 cb
-    mov al, byte [bx+048cch]                  ; 8a 87 cc 48
+    mov al, byte [bx+046d1h]                  ; 8a 87 d1 46
     mov dx, 003c2h                            ; ba c2 03
     out DX, AL                                ; ee
     mov AL, strict byte 020h                  ; b0 20
@@ -2395,9 +2406,9 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     jne short 01230h                          ; 75 5f
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
+    cmp byte [bx+04635h], 000h                ; 80 bf 35 46 00
     jne short 011f2h                          ; 75 13
-    mov es, [bx+04833h]                       ; 8e 87 33 48
+    mov es, [bx+04638h]                       ; 8e 87 38 46
     mov cx, 04000h                            ; b9 00 40
     mov ax, 00720h                            ; b8 20 07
     xor di, di                                ; 31 ff
@@ -2407,7 +2418,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     jmp short 01230h                          ; eb 3e
     cmp byte [bp-00ch], 00dh                  ; 80 7e f4 0d
     jnc short 0120ah                          ; 73 12
-    mov es, [bx+04833h]                       ; 8e 87 33 48
+    mov es, [bx+04638h]                       ; 8e 87 38 46
     mov cx, 04000h                            ; b9 00 40
     xor ax, ax                                ; 31 c0
     xor di, di                                ; 31 ff
@@ -2425,7 +2436,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     mov word [bp-01ah], ax                    ; 89 46 e6
     mov AL, strict byte 00fh                  ; b0 0f
     out DX, AL                                ; ee
-    mov es, [bx+04833h]                       ; 8e 87 33 48
+    mov es, [bx+04638h]                       ; 8e 87 38 46
     mov cx, 08000h                            ; b9 00 80
     xor ax, ax                                ; 31 c0
     xor di, di                                ; 31 ff
@@ -2444,7 +2455,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     call 02f68h                               ; e8 1f 1d
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     sal bx, 006h                              ; c1 e3 06
-    mov bx, word [bx+048c6h]                  ; 8b 9f c6 48
+    mov bx, word [bx+046cbh]                  ; 8b 9f cb 46
     mov dx, strict word 0004ch                ; ba 4c 00
     mov ax, strict word 00040h                ; b8 40 00
     call 02f68h                               ; e8 0b 1d
@@ -2483,7 +2494,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     mov ax, strict word 00040h                ; b8 40 00
     call 02f4ch                               ; e8 8b 1c
     mov cx, ds                                ; 8c d9
-    mov bx, 05593h                            ; bb 93 55
+    mov bx, 053d6h                            ; bb d6 53
     mov dx, 000a8h                            ; ba a8 00
     mov ax, strict word 00040h                ; b8 40 00
     call 02f88h                               ; e8 b9 1c
@@ -2497,7 +2508,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     call 02f4ch                               ; e8 67 1c
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
+    cmp byte [bx+04635h], 000h                ; 80 bf 35 46 00
     jne short 012fch                          ; 75 09
     mov dx, strict word 00007h                ; ba 07 00
     mov ax, strict word 00006h                ; b8 06 00
@@ -2515,7 +2526,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     call 00f00h                               ; e8 eb fb
     movzx bx, byte [bp-012h]                  ; 0f b6 5e ee
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
+    cmp byte [bx+04635h], 000h                ; 80 bf 35 46 00
     jne short 01333h                          ; 75 10
     xor bl, bl                                ; 30 db
     mov AL, strict byte 004h                  ; b0 04
@@ -2525,7 +2536,7 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     mov AL, strict byte 003h                  ; b0 03
     mov AH, strict byte 011h                  ; b4 11
     int 010h                                  ; cd 10
-    mov dx, 059afh                            ; ba af 59
+    mov dx, 057f2h                            ; ba f2 57
     mov ax, strict word 0001fh                ; b8 1f 00
     call 00a00h                               ; e8 c4 f6
     mov ax, word [bp-014h]                    ; 8b 46 ec
@@ -2535,13 +2546,13 @@ biosfn_set_video_mode_:                      ; 0xc0fdc LB 0x391
     je short 01359h                           ; 74 10
     cmp ax, strict word 00008h                ; 3d 08 00
     jne short 01363h                          ; 75 15
-    mov dx, 055afh                            ; ba af 55
+    mov dx, 053f2h                            ; ba f2 53
     mov ax, strict word 00043h                ; b8 43 00
     call 00a00h                               ; e8 a9 f6
     jmp short 01363h                          ; eb 0a
-    mov dx, 05dafh                            ; ba af 5d
+    mov dx, 05bf2h                            ; ba f2 5b
     jmp short 01351h                          ; eb f3
-    mov dx, 06bafh                            ; ba af 6b
+    mov dx, 069f2h                            ; ba f2 69
     jmp short 01351h                          ; eb ee
     lea sp, [bp-00ah]                         ; 8d 66 f6
     pop di                                    ; 5f
@@ -2851,7 +2862,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     mov word [bp-01ah], ax                    ; 89 46 e6
     mov ax, word [bp-016h]                    ; 8b 46 ea
     imul ax, cx                               ; 0f af c1
-    cmp byte [di+04830h], 000h                ; 80 bd 30 48 00
+    cmp byte [di+04635h], 000h                ; 80 bd 35 46 00
     jne near 017d1h                           ; 0f 85 9f 01
     mov dx, ax                                ; 89 c2
     add dx, ax                                ; 01 c2
@@ -2874,7 +2885,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     movzx dx, byte [bp-00ch]                  ; 0f b6 56 f4
     sal dx, 008h                              ; c1 e2 08
     add dx, strict byte 00020h                ; 83 c2 20
-    mov es, [di+04833h]                       ; 8e 85 33 48
+    mov es, [di+04638h]                       ; 8e 85 38 46
     mov cx, ax                                ; 89 c1
     mov ax, dx                                ; 89 d0
     mov di, bx                                ; 89 df
@@ -2908,7 +2919,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     add di, dx                                ; 01 d7
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov es, [si+04833h]                       ; 8e 84 33 48
+    mov es, [si+04638h]                       ; 8e 84 38 46
     cld                                       ; fc
     jcxz 016ddh                               ; e3 02
     rep stosw                                 ; f3 ab
@@ -2922,7 +2933,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     add dx, dx                                ; 01 d2
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov ax, word [si+04833h]                  ; 8b 84 33 48
+    mov ax, word [si+04638h]                  ; 8b 84 38 46
     mov si, word [bp-014h]                    ; 8b 76 ec
     imul si, word [bp-016h]                   ; 0f af 76 ea
     add cx, si                                ; 01 f1
@@ -2966,7 +2977,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     add di, dx                                ; 01 d7
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov es, [si+04833h]                       ; 8e 84 33 48
+    mov es, [si+04638h]                       ; 8e 84 38 46
     cld                                       ; fc
     jcxz 0177eh                               ; e3 02
     rep stosw                                 ; f3 ab
@@ -2981,7 +2992,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     add dx, dx                                ; 01 d2
     movzx si, byte [bp-00eh]                  ; 0f b6 76 f2
     sal si, 003h                              ; c1 e6 03
-    mov ax, word [si+04833h]                  ; 8b 84 33 48
+    mov ax, word [si+04638h]                  ; 8b 84 38 46
     mov si, word [bp-014h]                    ; 8b 76 ec
     imul si, word [bp-016h]                   ; 0f af 76 ea
     add di, si                                ; 01 f7
@@ -3001,11 +3012,11 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     jc near 01a6fh                            ; 0f 82 a4 02
     dec word [bp-014h]                        ; ff 4e ec
     jmp near 0172dh                           ; e9 5c ff
-    movzx bx, byte [si+048afh]                ; 0f b6 9c af 48
+    movzx bx, byte [si+046b4h]                ; 0f b6 9c b4 46
     sal bx, 006h                              ; c1 e3 06
-    mov dl, byte [bx+048c5h]                  ; 8a 97 c5 48
+    mov dl, byte [bx+046cah]                  ; 8a 97 ca 46
     mov byte [bp-00ah], dl                    ; 88 56 f6
-    mov bl, byte [di+04831h]                  ; 8a 9d 31 48
+    mov bl, byte [di+04636h]                  ; 8a 9d 36 46
     cmp bl, 004h                              ; 80 fb 04
     je short 017f8h                           ; 74 0f
     cmp bl, 003h                              ; 80 fb 03
@@ -3038,7 +3049,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     movzx ax, byte [bp-00ch]                  ; 0f b6 46 f4
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     sal bx, 003h                              ; c1 e3 03
-    mov es, [bx+04833h]                       ; 8e 87 33 48
+    mov es, [bx+04638h]                       ; 8e 87 38 46
     xor di, di                                ; 31 ff
     cld                                       ; fc
     jcxz 01849h                               ; e3 02
@@ -3120,7 +3131,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     jc near 01a6fh                            ; 0f 82 3d 01
     dec word [bp-014h]                        ; ff 4e ec
     jmp short 018c6h                          ; eb 8f
-    mov dl, byte [di+04832h]                  ; 8a 95 32 48
+    mov dl, byte [di+04637h]                  ; 8a 95 37 46
     cmp byte [bp-010h], 000h                  ; 80 7e f0 00
     jne short 0197eh                          ; 75 3d
     cmp byte [bp-008h], 000h                  ; 80 7e f8 00
@@ -3138,7 +3149,7 @@ biosfn_scroll_:                              ; 0xc1572 LB 0x506
     movzx cx, dl                              ; 0f b6 ca
     imul cx, ax                               ; 0f af c8
     movzx ax, byte [bp-00ch]                  ; 0f b6 46 f4
-    mov es, [di+04833h]                       ; 8e 85 33 48
+    mov es, [di+04638h]                       ; 8e 85 38 46
     xor di, di                                ; 31 ff
     cld                                       ; fc
     jcxz 0197bh                               ; e3 02
@@ -3240,11 +3251,11 @@ write_gfx_char_pl4_:                         ; 0xc1a78 LB 0xeb
     je short 01a96h                           ; 74 0b
     cmp byte [bp+006h], 00eh                  ; 80 7e 06 0e
     jne short 01a9bh                          ; 75 0a
-    mov di, 05dafh                            ; bf af 5d
+    mov di, 05bf2h                            ; bf f2 5b
     jmp short 01a9eh                          ; eb 08
-    mov di, 06bafh                            ; bf af 6b
+    mov di, 069f2h                            ; bf f2 69
     jmp short 01a9eh                          ; eb 03
-    mov di, 055afh                            ; bf af 55
+    mov di, 053f2h                            ; bf f2 53
     movzx si, cl                              ; 0f b6 f1
     movzx bx, byte [bp+006h]                  ; 0f b6 5e 06
     imul si, bx                               ; 0f af f3
@@ -3331,7 +3342,7 @@ write_gfx_char_cga_:                         ; 0xc1b63 LB 0x11e
     push di                                   ; 57
     sub sp, strict byte 00008h                ; 83 ec 08
     mov byte [bp-008h], dl                    ; 88 56 f8
-    mov si, 055afh                            ; be af 55
+    mov si, 053f2h                            ; be f2 53
     xor bh, bh                                ; 30 ff
     movzx di, byte [bp+006h]                  ; 0f b6 7e 06
     imul di, bx                               ; 0f af fb
@@ -3445,7 +3456,7 @@ write_gfx_char_lin_:                         ; 0xc1c81 LB 0x91
     push di                                   ; 57
     sub sp, strict byte 00008h                ; 83 ec 08
     mov byte [bp-006h], dl                    ; 88 56 fa
-    mov di, 055afh                            ; bf af 55
+    mov di, 053f2h                            ; bf f2 53
     movzx dx, cl                              ; 0f b6 d1
     movzx cx, byte [bp+004h]                  ; 0f b6 4e 04
     imul cx, dx                               ; 0f af ca
@@ -3540,7 +3551,7 @@ biosfn_write_char_attr_:                     ; 0xc1d12 LB 0x168
     movzx bx, cl                              ; 0f b6 d9
     mov di, bx                                ; 89 df
     sal di, 003h                              ; c1 e7 03
-    cmp byte [di+04830h], 000h                ; 80 bd 30 48 00
+    cmp byte [di+04635h], 000h                ; 80 bd 35 46 00
     jne short 01dcdh                          ; 75 47
     mov bx, word [bp-018h]                    ; 8b 5e e8
     imul bx, ax                               ; 0f af d8
@@ -3561,18 +3572,18 @@ biosfn_write_char_attr_:                     ; 0xc1d12 LB 0x168
     add ax, bx                                ; 01 d8
     mov word [bp-01ah], ax                    ; 89 46 e6
     mov ax, word [bp-01ah]                    ; 8b 46 e6
-    mov es, [di+04833h]                       ; 8e 85 33 48
+    mov es, [di+04638h]                       ; 8e 85 38 46
     mov cx, si                                ; 89 f1
     mov di, dx                                ; 89 d7
     cld                                       ; fc
     jcxz 01dcah                               ; e3 02
     rep stosw                                 ; f3 ab
     jmp near 01e73h                           ; e9 a6 00
-    movzx bx, byte [bx+048afh]                ; 0f b6 9f af 48
+    movzx bx, byte [bx+046b4h]                ; 0f b6 9f b4 46
     sal bx, 006h                              ; c1 e3 06
-    mov al, byte [bx+048c5h]                  ; 8a 87 c5 48
+    mov al, byte [bx+046cah]                  ; 8a 87 ca 46
     mov byte [bp-008h], al                    ; 88 46 f8
-    mov al, byte [di+04832h]                  ; 8a 85 32 48
+    mov al, byte [di+04637h]                  ; 8a 85 37 46
     mov byte [bp-014h], al                    ; 88 46 ec
     dec si                                    ; 4e
     cmp si, strict byte 0ffffh                ; 83 fe ff
@@ -3582,7 +3593,7 @@ biosfn_write_char_attr_:                     ; 0xc1d12 LB 0x168
     jnc near 01e73h                           ; 0f 83 7d 00
     movzx bx, byte [bp-006h]                  ; 0f b6 5e fa
     sal bx, 003h                              ; c1 e3 03
-    mov al, byte [bx+04831h]                  ; 8a 87 31 48
+    mov al, byte [bx+04636h]                  ; 8a 87 36 46
     cmp AL, strict byte 003h                  ; 3c 03
     jc short 01e11h                           ; 72 0c
     jbe short 01e17h                          ; 76 10
@@ -3670,7 +3681,7 @@ biosfn_write_char_only_:                     ; 0xc1e7a LB 0x16f
     movzx di, cl                              ; 0f b6 f9
     mov bx, di                                ; 89 fb
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
+    cmp byte [bx+04635h], 000h                ; 80 bf 35 46 00
     jne short 01f38h                          ; 75 4a
     mov dx, word [bp-018h]                    ; 8b 56 e8
     imul dx, ax                               ; 0f af d0
@@ -3692,7 +3703,7 @@ biosfn_write_char_only_:                     ; 0xc1e7a LB 0x16f
     movzx ax, byte [bp-012h]                  ; 0f b6 46 ee
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     sal bx, 003h                              ; c1 e3 03
-    mov di, word [bx+04833h]                  ; 8b bf 33 48
+    mov di, word [bx+04638h]                  ; 8b bf 38 46
     mov bx, ax                                ; 89 c3
     mov dx, cx                                ; 89 ca
     mov ax, di                                ; 89 f8
@@ -3700,11 +3711,11 @@ biosfn_write_char_only_:                     ; 0xc1e7a LB 0x16f
     inc cx                                    ; 41
     inc cx                                    ; 41
     jmp short 01f14h                          ; eb dc
-    movzx di, byte [di+048afh]                ; 0f b6 bd af 48
+    movzx di, byte [di+046b4h]                ; 0f b6 bd b4 46
     sal di, 006h                              ; c1 e7 06
-    mov al, byte [di+048c5h]                  ; 8a 85 c5 48
+    mov al, byte [di+046cah]                  ; 8a 85 ca 46
     mov byte [bp-00ah], al                    ; 88 46 f6
-    mov al, byte [bx+04832h]                  ; 8a 87 32 48
+    mov al, byte [bx+04637h]                  ; 8a 87 37 46
     mov byte [bp-008h], al                    ; 88 46 f8
     dec si                                    ; 4e
     cmp si, strict byte 0ffffh                ; 83 fe ff
@@ -3714,7 +3725,7 @@ biosfn_write_char_only_:                     ; 0xc1e7a LB 0x16f
     jnc near 01fe2h                           ; 0f 83 81 00
     movzx bx, byte [bp-00eh]                  ; 0f b6 5e f2
     sal bx, 003h                              ; c1 e3 03
-    mov bl, byte [bx+04831h]                  ; 8a 9f 31 48
+    mov bl, byte [bx+04636h]                  ; 8a 9f 36 46
     cmp bl, 003h                              ; 80 fb 03
     jc short 01f7fh                           ; 72 0e
     jbe short 01f86h                          ; 76 13
@@ -3777,9 +3788,9 @@ biosfn_write_pixel_:                         ; 0xc1fe9 LB 0x16a
     je near 0212bh                            ; 0f 84 1e 01
     movzx bx, al                              ; 0f b6 d8
     sal bx, 003h                              ; c1 e3 03
-    cmp byte [bx+04830h], 000h                ; 80 bf 30 48 00
+    cmp byte [bx+04635h], 000h                ; 80 bf 35 46 00
     je near 0212bh                            ; 0f 84 0f 01
-    mov al, byte [bx+04831h]                  ; 8a 87 31 48
+    mov al, byte [bx+04636h]                  ; 8a 87 36 46
     cmp AL, strict byte 003h                  ; 3c 03
     jc short 02033h                           ; 72 0f
     jbe short 0203ah                          ; 76 14
@@ -3833,7 +3844,7 @@ biosfn_write_pixel_:                         ; 0xc1fe9 LB 0x16a
     mov ax, cx                                ; 89 c8
     shr ax, 1                                 ; d1 e8
     imul ax, ax, strict byte 00050h           ; 6b c0 50
-    cmp byte [bx+04832h], 002h                ; 80 bf 32 48 02
+    cmp byte [bx+04637h], 002h                ; 80 bf 37 46 02
     jne short 020b5h                          ; 75 08
     mov bx, word [bp-00ah]                    ; 8b 5e f6
     shr bx, 002h                              ; c1 eb 02
@@ -3851,7 +3862,7 @@ biosfn_write_pixel_:                         ; 0xc1fe9 LB 0x16a
     mov bl, al                                ; 88 c3
     movzx si, byte [bp-004h]                  ; 0f b6 76 fc
     sal si, 003h                              ; c1 e6 03
-    cmp byte [si+04832h], 002h                ; 80 bc 32 48 02
+    cmp byte [si+04637h], 002h                ; 80 bc 37 46 02
     jne short 020fbh                          ; 75 19
     mov al, byte [bp-00ah]                    ; 8a 46 f6
     and AL, strict byte 003h                  ; 24 03
@@ -3964,7 +3975,7 @@ biosfn_write_teletype_:                      ; 0xc2153 LB 0x241
     movzx bx, byte [bp-010h]                  ; 0f b6 5e f0
     mov si, bx                                ; 89 de
     sal si, 003h                              ; c1 e6 03
-    cmp byte [si+04830h], 000h                ; 80 bc 30 48 00
+    cmp byte [si+04635h], 000h                ; 80 bc 35 46 00
     jne short 02256h                          ; 75 4d
     mov ax, word [bp-012h]                    ; 8b 46 ee
     imul ax, word [bp-014h]                   ; 0f af 46 ec
@@ -3981,7 +3992,7 @@ biosfn_write_teletype_:                      ; 0xc2153 LB 0x241
     add ax, ax                                ; 01 c0
     add cx, ax                                ; 01 c1
     movzx bx, byte [bp-00ch]                  ; 0f b6 5e f4
-    mov ax, word [si+04833h]                  ; 8b 84 33 48
+    mov ax, word [si+04638h]                  ; 8b 84 38 46
     mov dx, cx                                ; 89 ca
     call 02f4ch                               ; e8 0f 0d
     cmp byte [bp-00eh], 003h                  ; 80 7e f2 03
@@ -3989,14 +4000,14 @@ biosfn_write_teletype_:                      ; 0xc2153 LB 0x241
     movzx bx, byte [bp-004h]                  ; 0f b6 5e fc
     mov dx, cx                                ; 89 ca
     inc dx                                    ; 42
-    mov ax, word [si+04833h]                  ; 8b 84 33 48
+    mov ax, word [si+04638h]                  ; 8b 84 38 46
     call 02f4ch                               ; e8 f9 0c
     jmp near 022d4h                           ; e9 7e 00
-    movzx bx, byte [bx+048afh]                ; 0f b6 9f af 48
+    movzx bx, byte [bx+046b4h]                ; 0f b6 9f b4 46
     sal bx, 006h                              ; c1 e3 06
-    mov ah, byte [bx+048c5h]                  ; 8a a7 c5 48
-    mov dl, byte [si+04832h]                  ; 8a 94 32 48
-    mov al, byte [si+04831h]                  ; 8a 84 31 48
+    mov ah, byte [bx+046cah]                  ; 8a a7 ca 46
+    mov dl, byte [si+04637h]                  ; 8a 94 37 46
+    mov al, byte [si+04636h]                  ; 8a 84 36 46
     cmp AL, strict byte 003h                  ; 3c 03
     jc short 0227ah                           ; 72 0c
     jbe short 02280h                          ; 76 10
@@ -4052,7 +4063,7 @@ biosfn_write_teletype_:                      ; 0xc2153 LB 0x241
     mov bl, byte [bp-012h]                    ; 8a 5e ee
     db  0feh, 0cbh
     ; dec bl                                    ; fe cb
-    cmp byte [si+04830h], 000h                ; 80 bc 30 48 00
+    cmp byte [si+04635h], 000h                ; 80 bc 35 46 00
     jne short 02354h                          ; 75 4a
     mov ax, word [bp-012h]                    ; 8b 46 ee
     imul ax, word [bp-014h]                   ; 0f af 46 ec
@@ -4071,7 +4082,7 @@ biosfn_write_teletype_:                      ; 0xc2153 LB 0x241
     mov dx, cx                                ; 89 ca
     add dx, ax                                ; 01 c2
     inc dx                                    ; 42
-    mov ax, word [si+04833h]                  ; 8b 84 33 48
+    mov ax, word [si+04638h]                  ; 8b 84 38 46
     call 02f3eh                               ; e8 02 0c
     push strict byte 00001h                   ; 6a 01
     movzx dx, byte [bp-006h]                  ; 0f b6 56 fa
@@ -4346,7 +4357,7 @@ biosfn_load_text_8_14_pat_:                  ; 0xc2538 LB 0x70
     mov di, bx                                ; 89 df
     sal di, 005h                              ; c1 e7 05
     add di, word [bp-00ch]                    ; 03 7e f4
-    add si, 05dafh                            ; 81 c6 af 5d
+    add si, 05bf2h                            ; 81 c6 f2 5b
     mov cx, strict word 0000eh                ; b9 0e 00
     mov dx, 0c000h                            ; ba 00 c0
     mov ax, 0a000h                            ; b8 00 a0
@@ -4402,7 +4413,7 @@ biosfn_load_text_8_8_pat_:                   ; 0xc25a8 LB 0x72
     mov di, bx                                ; 89 df
     sal di, 005h                              ; c1 e7 05
     add di, word [bp-00ch]                    ; 03 7e f4
-    add si, 055afh                            ; 81 c6 af 55
+    add si, 053f2h                            ; 81 c6 f2 53
     mov cx, strict word 00008h                ; b9 08 00
     mov dx, 0c000h                            ; ba 00 c0
     mov ax, 0a000h                            ; b8 00 a0
@@ -4458,7 +4469,7 @@ biosfn_load_text_8_16_pat_:                  ; 0xc261a LB 0x72
     mov di, bx                                ; 89 df
     sal di, 005h                              ; c1 e7 05
     add di, word [bp-00ch]                    ; 03 7e f4
-    add si, 06bafh                            ; 81 c6 af 6b
+    add si, 069f2h                            ; 81 c6 f2 69
     mov cx, strict word 00010h                ; b9 10 00
     mov dx, 0c000h                            ; ba 00 c0
     mov ax, 0a000h                            ; b8 00 a0
@@ -4592,7 +4603,7 @@ biosfn_read_state_info_:                     ; 0xc2752 LB 0x101
     push dx                                   ; 52
     push bx                                   ; 53
     mov cx, ds                                ; 8c d9
-    mov bx, 05583h                            ; bb 83 55
+    mov bx, 05388h                            ; bb 88 53
     mov dx, word [bp-00ah]                    ; 8b 56 f6
     mov ax, word [bp-008h]                    ; 8b 46 f8
     call 02f88h                               ; e8 20 08
@@ -5492,7 +5503,7 @@ find_vga_entry_:                             ; 0xc2f17 LB 0x27
     jnbe short 02f38h                         ; 77 0e
     movzx bx, al                              ; 0f b6 d8
     sal bx, 003h                              ; c1 e3 03
-    cmp dl, byte [bx+0482fh]                  ; 3a 97 2f 48
+    cmp dl, byte [bx+04634h]                  ; 3a 97 34 46
     jne short 02f24h                          ; 75 ee
     mov ah, al                                ; 88 c4
     mov al, ah                                ; 88 e0
@@ -5928,7 +5939,7 @@ _int10_func:                                 ; 0xc3007 LB 0x3ca
     xor al, al                                ; 30 c0
     or AL, strict byte 01ch                   ; 0c 1c
     jmp near 0306dh                           ; e9 20 fd
-    call 007a4h                               ; e8 54 d4
+    call 007fah                               ; e8 aa d4
     test ax, ax                               ; 85 c0
     je near 033c5h                            ; 0f 84 6f 00
     mov ax, word [bp+012h]                    ; 8b 46 12
@@ -5950,19 +5961,19 @@ _int10_func:                                 ; 0xc3007 LB 0x3ca
     mov bx, si                                ; 89 f3
     mov dx, word [bp+016h]                    ; 8b 56 16
     lea ax, [bp+012h]                         ; 8d 46 12
-    call 034f7h                               ; e8 70 01
+    call 03503h                               ; e8 7c 01
     jmp short 033cah                          ; eb 41
     mov cx, si                                ; 89 f1
     mov bx, word [bp+016h]                    ; 8b 5e 16
     mov dx, word [bp+010h]                    ; 8b 56 10
     lea ax, [bp+012h]                         ; 8d 46 12
-    call 03620h                               ; e8 89 02
+    call 0362ch                               ; e8 95 02
     jmp short 033cah                          ; eb 31
     mov cx, si                                ; 89 f1
     mov bx, word [bp+016h]                    ; 8b 5e 16
     mov dx, word [bp+00ch]                    ; 8b 56 0c
     lea ax, [bp+012h]                         ; 8d 46 12
-    call 036d4h                               ; e8 2d 03
+    call 036e4h                               ; e8 3d 03
     jmp short 033cah                          ; eb 21
     lea ax, [bp+00ch]                         ; 8d 46 0c
     push ax                                   ; 50
@@ -5970,7 +5981,7 @@ _int10_func:                                 ; 0xc3007 LB 0x3ca
     mov bx, word [bp+00eh]                    ; 8b 5e 0e
     mov dx, word [bp+010h]                    ; 8b 56 10
     lea ax, [bp+012h]                         ; 8d 46 12
-    call 038bbh                               ; e8 ff 04
+    call 038cbh                               ; e8 0f 05
     jmp short 033cah                          ; eb 0c
     mov word [bp+012h], 00100h                ; c7 46 12 00 01
     jmp short 033cah                          ; eb 05
@@ -5980,7 +5991,7 @@ _int10_func:                                 ; 0xc3007 LB 0x3ca
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-dispi_set_xres_:                             ; 0xc33d1 LB 0x1b
+dispi_set_xres_:                             ; 0xc33d1 LB 0x1f
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -5988,16 +5999,16 @@ dispi_set_xres_:                             ; 0xc33d1 LB 0x1b
     mov bx, ax                                ; 89 c3
     mov ax, strict word 00001h                ; b8 01 00
     mov dx, 001ceh                            ; ba ce 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 8f d1
     mov ax, bx                                ; 89 d8
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 87 d1
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop dx                                    ; 5a
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-dispi_set_yres_:                             ; 0xc33ec LB 0x1b
+dispi_set_yres_:                             ; 0xc33f0 LB 0x1f
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6005,16 +6016,16 @@ dispi_set_yres_:                             ; 0xc33ec LB 0x1b
     mov bx, ax                                ; 89 c3
     mov ax, strict word 00002h                ; b8 02 00
     mov dx, 001ceh                            ; ba ce 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 70 d1
     mov ax, bx                                ; 89 d8
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 68 d1
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop dx                                    ; 5a
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-dispi_set_bpp_:                              ; 0xc3407 LB 0x1b
+dispi_set_bpp_:                              ; 0xc340f LB 0x1f
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6022,16 +6033,16 @@ dispi_set_bpp_:                              ; 0xc3407 LB 0x1b
     mov bx, ax                                ; 89 c3
     mov ax, strict word 00003h                ; b8 03 00
     mov dx, 001ceh                            ; ba ce 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 51 d1
     mov ax, bx                                ; 89 d8
     mov dx, 001cfh                            ; ba cf 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 49 d1
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop dx                                    ; 5a
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-in_word_:                                    ; 0xc3422 LB 0x12
+in_word_:                                    ; 0xc342e LB 0x12
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6044,7 +6055,7 @@ in_word_:                                    ; 0xc3422 LB 0x12
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-in_byte_:                                    ; 0xc3434 LB 0x14
+in_byte_:                                    ; 0xc3440 LB 0x14
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6059,7 +6070,7 @@ in_byte_:                                    ; 0xc3434 LB 0x14
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-dispi_get_id_:                               ; 0xc3448 LB 0x14
+dispi_get_id_:                               ; 0xc3454 LB 0x14
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push dx                                   ; 52
@@ -6072,7 +6083,7 @@ dispi_get_id_:                               ; 0xc3448 LB 0x14
     pop dx                                    ; 5a
     pop bp                                    ; 5d
     retn                                      ; c3
-dispi_set_id_:                               ; 0xc345c LB 0x1a
+dispi_set_id_:                               ; 0xc3468 LB 0x1a
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6089,28 +6100,28 @@ dispi_set_id_:                               ; 0xc345c LB 0x1a
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_init_:                                   ; 0xc3476 LB 0x2c
+vbe_init_:                                   ; 0xc3482 LB 0x2c
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
     push dx                                   ; 52
     mov ax, 0b0c0h                            ; b8 c0 b0
-    call 0345ch                               ; e8 db ff
-    call 03448h                               ; e8 c4 ff
+    call 03468h                               ; e8 db ff
+    call 03454h                               ; e8 c4 ff
     cmp ax, 0b0c0h                            ; 3d c0 b0
-    jne short 0349bh                          ; 75 12
+    jne short 034a7h                          ; 75 12
     mov bx, strict word 00001h                ; bb 01 00
     mov dx, 000b9h                            ; ba b9 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 02f4ch                               ; e8 b7 fa
+    call 02f4ch                               ; e8 ab fa
     mov ax, 0b0c4h                            ; b8 c4 b0
-    call 0345ch                               ; e8 c1 ff
+    call 03468h                               ; e8 c1 ff
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop dx                                    ; 5a
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-mode_info_find_mode_:                        ; 0xc34a2 LB 0x55
+mode_info_find_mode_:                        ; 0xc34ae LB 0x55
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6121,30 +6132,30 @@ mode_info_find_mode_:                        ; 0xc34a2 LB 0x55
     mov si, dx                                ; 89 d6
     xor dx, dx                                ; 31 d2
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 6d ff
+    call 0342eh                               ; e8 6d ff
     cmp ax, 077cch                            ; 3d cc 77
-    jne short 034ech                          ; 75 32
+    jne short 034f8h                          ; 75 32
     mov bx, strict word 00004h                ; bb 04 00
     mov dx, bx                                ; 89 da
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 5d ff
+    call 0342eh                               ; e8 5d ff
     mov cx, ax                                ; 89 c1
     cmp cx, strict byte 0ffffh                ; 83 f9 ff
-    je short 034ech                           ; 74 20
+    je short 034f8h                           ; 74 20
     lea dx, [bx+002h]                         ; 8d 57 02
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 4d ff
+    call 0342eh                               ; e8 4d ff
     lea dx, [bx+044h]                         ; 8d 57 44
     cmp cx, di                                ; 39 f9
-    jne short 034e8h                          ; 75 0c
+    jne short 034f4h                          ; 75 0c
     test si, si                               ; 85 f6
-    jne short 034e4h                          ; 75 04
+    jne short 034f0h                          ; 75 04
     mov ax, bx                                ; 89 d8
-    jmp short 034eeh                          ; eb 0a
+    jmp short 034fah                          ; eb 0a
     test AL, strict byte 080h                 ; a8 80
-    jne short 034e0h                          ; 75 f8
+    jne short 034ech                          ; 75 f8
     mov bx, dx                                ; 89 d3
-    jmp short 034bfh                          ; eb d3
+    jmp short 034cbh                          ; eb d3
     xor ax, ax                                ; 31 c0
     lea sp, [bp-008h]                         ; 8d 66 f8
     pop di                                    ; 5f
@@ -6153,7 +6164,7 @@ mode_info_find_mode_:                        ; 0xc34a2 LB 0x55
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_biosfn_return_controller_information_: ; 0xc34f7 LB 0x129
+vbe_biosfn_return_controller_information_: ; 0xc3503 LB 0x129
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -6164,36 +6175,36 @@ vbe_biosfn_return_controller_information_: ; 0xc34f7 LB 0x129
     mov di, dx                                ; 89 d7
     mov word [bp-00ah], bx                    ; 89 5e f6
     mov word [bp-00ch], strict word 00022h    ; c7 46 f4 22 00
-    call 005a7h                               ; e8 98 d0
+    call 005b7h                               ; e8 9c d0
     mov word [bp-010h], ax                    ; 89 46 f0
     mov bx, word [bp-00ah]                    ; 8b 5e f6
     mov word [bp-008h], di                    ; 89 7e f8
     xor dx, dx                                ; 31 d2
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 02 ff
+    call 0342eh                               ; e8 02 ff
     cmp ax, 077cch                            ; 3d cc 77
-    je short 0352fh                           ; 74 0a
+    je short 0353bh                           ; 74 0a
     push SS                                   ; 16
     pop ES                                    ; 07
     mov word [es:si], 00100h                  ; 26 c7 04 00 01
-    jmp near 03618h                           ; e9 e9 00
+    jmp near 03624h                           ; e9 e9 00
     mov cx, strict word 00004h                ; b9 04 00
     mov word [bp-00eh], strict word 00000h    ; c7 46 f2 00 00
     mov es, [bp-008h]                         ; 8e 46 f8
     cmp word [es:bx+002h], 03245h             ; 26 81 7f 02 45 32
-    jne short 03549h                          ; 75 07
+    jne short 03555h                          ; 75 07
     cmp word [es:bx], 04256h                  ; 26 81 3f 56 42
-    je short 03558h                           ; 74 0f
+    je short 03564h                           ; 74 0f
     cmp word [es:bx+002h], 04153h             ; 26 81 7f 02 53 41
-    jne short 0355dh                          ; 75 0c
+    jne short 03569h                          ; 75 0c
     cmp word [es:bx], 04556h                  ; 26 81 3f 56 45
-    jne short 0355dh                          ; 75 05
+    jne short 03569h                          ; 75 05
     mov word [bp-00eh], strict word 00001h    ; c7 46 f2 01 00
     mov es, [bp-008h]                         ; 8e 46 f8
     db  066h, 026h, 0c7h, 007h, 056h, 045h, 053h, 041h
     ; mov dword [es:bx], strict dword 041534556h ; 66 26 c7 07 56 45 53 41
     mov word [es:bx+004h], 00200h             ; 26 c7 47 04 00 02
-    mov word [es:bx+006h], 07e20h             ; 26 c7 47 06 20 7e
+    mov word [es:bx+006h], 07c64h             ; 26 c7 47 06 64 7c
     mov [es:bx+008h], ds                      ; 26 8c 5f 08
     db  066h, 026h, 0c7h, 047h, 00ah, 001h, 000h, 000h, 000h
     ; mov dword [es:bx+00ah], strict dword 000000001h ; 66 26 c7 47 0a 01 00 00 00
@@ -6203,45 +6214,45 @@ vbe_biosfn_return_controller_information_: ; 0xc34f7 LB 0x129
     mov word [es:bx+00eh], ax                 ; 26 89 47 0e
     mov dx, strict word 0ffffh                ; ba ff ff
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 8a fe
+    call 0342eh                               ; e8 8a fe
     mov es, [bp-008h]                         ; 8e 46 f8
     mov word [es:bx+012h], ax                 ; 26 89 47 12
     cmp word [bp-00eh], strict byte 00000h    ; 83 7e f2 00
-    je short 035c9h                           ; 74 24
+    je short 035d5h                           ; 74 24
     mov word [es:bx+014h], strict word 00003h ; 26 c7 47 14 03 00
-    mov word [es:bx+016h], 07e35h             ; 26 c7 47 16 35 7e
+    mov word [es:bx+016h], 07c79h             ; 26 c7 47 16 79 7c
     mov [es:bx+018h], ds                      ; 26 8c 5f 18
-    mov word [es:bx+01ah], 07e48h             ; 26 c7 47 1a 48 7e
+    mov word [es:bx+01ah], 07c8ch             ; 26 c7 47 1a 8c 7c
     mov [es:bx+01ch], ds                      ; 26 8c 5f 1c
-    mov word [es:bx+01eh], 07e69h             ; 26 c7 47 1e 69 7e
+    mov word [es:bx+01eh], 07cadh             ; 26 c7 47 1e ad 7c
     mov [es:bx+020h], ds                      ; 26 8c 5f 20
     mov dx, cx                                ; 89 ca
     add dx, strict byte 0001bh                ; 83 c2 1b
     mov ax, 003b6h                            ; b8 b6 03
-    call 03434h                               ; e8 60 fe
+    call 03440h                               ; e8 60 fe
     xor ah, ah                                ; 30 e4
     cmp ax, word [bp-010h]                    ; 3b 46 f0
-    jnbe short 035f4h                         ; 77 19
+    jnbe short 03600h                         ; 77 19
     mov dx, cx                                ; 89 ca
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 3f fe
+    call 0342eh                               ; e8 3f fe
     mov bx, ax                                ; 89 c3
     mov dx, word [bp-00ah]                    ; 8b 56 f6
     add dx, word [bp-00ch]                    ; 03 56 f4
     mov ax, di                                ; 89 f8
-    call 02f68h                               ; e8 78 f9
+    call 02f68h                               ; e8 6c f9
     add word [bp-00ch], strict byte 00002h    ; 83 46 f4 02
     add cx, strict byte 00044h                ; 83 c1 44
     mov dx, cx                                ; 89 ca
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 23 fe
+    call 0342eh                               ; e8 23 fe
     mov bx, ax                                ; 89 c3
     cmp ax, strict word 0ffffh                ; 3d ff ff
-    jne short 035c9h                          ; 75 c3
+    jne short 035d5h                          ; 75 c3
     mov dx, word [bp-00ah]                    ; 8b 56 f6
     add dx, word [bp-00ch]                    ; 03 56 f4
     mov ax, di                                ; 89 f8
-    call 02f68h                               ; e8 57 f9
+    call 02f68h                               ; e8 4b f9
     push SS                                   ; 16
     pop ES                                    ; 07
     mov word [es:si], strict word 0004fh      ; 26 c7 04 4f 00
@@ -6251,7 +6262,7 @@ vbe_biosfn_return_controller_information_: ; 0xc34f7 LB 0x129
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_biosfn_return_mode_information_:         ; 0xc3620 LB 0xb4
+vbe_biosfn_return_mode_information_:         ; 0xc362c LB 0xb8
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -6267,63 +6278,63 @@ vbe_biosfn_return_mode_information_:         ; 0xc3620 LB 0xb4
     ; setne dl                                  ; 0f 95 c2
     xor dh, dh                                ; 30 f6
     and ah, 001h                              ; 80 e4 01
-    call 034a2h                               ; e8 65 fe
+    call 034aeh                               ; e8 65 fe
     mov word [bp-008h], ax                    ; 89 46 f8
     test ax, ax                               ; 85 c0
-    je near 036c2h                            ; 0f 84 7c 00
+    je near 036d2h                            ; 0f 84 80 00
     mov cx, 00100h                            ; b9 00 01
     xor ax, ax                                ; 31 c0
     mov di, word [bp-006h]                    ; 8b 7e fa
     mov es, bx                                ; 8e c3
     cld                                       ; fc
-    jcxz 03655h                               ; e3 02
+    jcxz 03661h                               ; e3 02
     rep stosb                                 ; f3 aa
     xor cx, cx                                ; 31 c9
-    jmp short 0365eh                          ; eb 05
+    jmp short 0366ah                          ; eb 05
     cmp cx, strict byte 00042h                ; 83 f9 42
-    jnc short 0367bh                          ; 73 1d
+    jnc short 03687h                          ; 73 1d
     mov dx, word [bp-008h]                    ; 8b 56 f8
     inc dx                                    ; 42
     inc dx                                    ; 42
     add dx, cx                                ; 01 ca
     mov ax, 003b6h                            ; b8 b6 03
-    call 03434h                               ; e8 c9 fd
+    call 03440h                               ; e8 c9 fd
     movzx bx, al                              ; 0f b6 d8
     mov dx, word [bp-006h]                    ; 8b 56 fa
     add dx, cx                                ; 01 ca
     mov ax, si                                ; 89 f0
-    call 02f4ch                               ; e8 d4 f8
+    call 02f4ch                               ; e8 c8 f8
     inc cx                                    ; 41
-    jmp short 03659h                          ; eb de
+    jmp short 03665h                          ; eb de
     mov dx, word [bp-006h]                    ; 8b 56 fa
     inc dx                                    ; 42
     inc dx                                    ; 42
     mov ax, si                                ; 89 f0
-    call 02f3eh                               ; e8 b9 f8
+    call 02f3eh                               ; e8 ad f8
     test AL, strict byte 001h                 ; a8 01
-    je short 036a5h                           ; 74 1c
+    je short 036b1h                           ; 74 1c
     mov dx, word [bp-006h]                    ; 8b 56 fa
     add dx, strict byte 0000ch                ; 83 c2 0c
-    mov bx, 00605h                            ; bb 05 06
+    mov bx, 00629h                            ; bb 29 06
     mov ax, si                                ; 89 f0
-    call 02f68h                               ; e8 d1 f8
+    call 02f68h                               ; e8 c5 f8
     mov dx, word [bp-006h]                    ; 8b 56 fa
     add dx, strict byte 0000eh                ; 83 c2 0e
     mov bx, 0c000h                            ; bb 00 c0
     mov ax, si                                ; 89 f0
-    call 02f68h                               ; e8 c3 f8
+    call 02f68h                               ; e8 b7 f8
     mov ax, strict word 0000bh                ; b8 0b 00
     mov dx, 001ceh                            ; ba ce 01
-    out DX, ax                                ; ef
+    call 00570h                               ; e8 b6 ce
     mov dx, 001cfh                            ; ba cf 01
-    in ax, DX                                 ; ed
+    call 00577h                               ; e8 b7 ce
     mov dx, word [bp-006h]                    ; 8b 56 fa
     add dx, strict byte 0002ah                ; 83 c2 2a
     mov bx, ax                                ; 89 c3
     mov ax, si                                ; 89 f0
-    call 02f68h                               ; e8 ab f8
+    call 02f68h                               ; e8 9b f8
     mov ax, strict word 0004fh                ; b8 4f 00
-    jmp short 036c5h                          ; eb 03
+    jmp short 036d5h                          ; eb 03
     mov ax, 00100h                            ; b8 00 01
     push SS                                   ; 16
     pop ES                                    ; 07
@@ -6334,7 +6345,7 @@ vbe_biosfn_return_mode_information_:         ; 0xc3620 LB 0xb4
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_biosfn_set_mode_:                        ; 0xc36d4 LB 0xe9
+vbe_biosfn_set_mode_:                        ; 0xc36e4 LB 0xe9
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -6348,75 +6359,75 @@ vbe_biosfn_set_mode_:                        ; 0xc36d4 LB 0xe9
     movzx dx, al                              ; 0f b6 d0
     mov ax, dx                                ; 89 d0
     test dx, dx                               ; 85 d2
-    je short 036f4h                           ; 74 03
+    je short 03704h                           ; 74 03
     mov dx, strict word 00040h                ; ba 40 00
     mov byte [bp-006h], dl                    ; 88 56 fa
     test byte [bp-009h], 080h                 ; f6 46 f7 80
-    je short 03702h                           ; 74 05
+    je short 03712h                           ; 74 05
     mov dx, 00080h                            ; ba 80 00
-    jmp short 03704h                          ; eb 02
+    jmp short 03714h                          ; eb 02
     xor dx, dx                                ; 31 d2
     mov byte [bp-008h], dl                    ; 88 56 f8
     and byte [bp-009h], 001h                  ; 80 66 f7 01
     cmp word [bp-00ah], 00100h                ; 81 7e f6 00 01
-    jnc short 03724h                          ; 73 12
+    jnc short 03734h                          ; 73 12
     xor ax, ax                                ; 31 c0
-    call 005c9h                               ; e8 b2 ce
+    call 005ddh                               ; e8 b6 ce
     movzx ax, byte [bp-00ah]                  ; 0f b6 46 f6
-    call 00fdch                               ; e8 be d8
+    call 00fdch                               ; e8 ae d8
     mov ax, strict word 0004fh                ; b8 4f 00
-    jmp near 037b3h                           ; e9 8f 00
+    jmp near 037c3h                           ; e9 8f 00
     mov dx, ax                                ; 89 c2
     mov ax, word [bp-00ah]                    ; 8b 46 f6
-    call 034a2h                               ; e8 76 fd
+    call 034aeh                               ; e8 72 fd
     mov bx, ax                                ; 89 c3
     test ax, ax                               ; 85 c0
-    je near 037b0h                            ; 0f 84 7c 00
+    je near 037c0h                            ; 0f 84 7c 00
     lea dx, [bx+014h]                         ; 8d 57 14
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 e5 fc
+    call 0342eh                               ; e8 e1 fc
     mov cx, ax                                ; 89 c1
     lea dx, [bx+016h]                         ; 8d 57 16
     mov ax, 003b6h                            ; b8 b6 03
-    call 03422h                               ; e8 da fc
+    call 0342eh                               ; e8 d6 fc
     mov di, ax                                ; 89 c7
     lea dx, [bx+01bh]                         ; 8d 57 1b
     mov ax, 003b6h                            ; b8 b6 03
-    call 03434h                               ; e8 e1 fc
+    call 03440h                               ; e8 dd fc
     mov bl, al                                ; 88 c3
     mov dl, al                                ; 88 c2
     xor ax, ax                                ; 31 c0
-    call 005c9h                               ; e8 6d ce
+    call 005ddh                               ; e8 71 ce
     cmp bl, 004h                              ; 80 fb 04
-    jne short 03767h                          ; 75 06
+    jne short 03777h                          ; 75 06
     mov ax, strict word 0006ah                ; b8 6a 00
-    call 00fdch                               ; e8 75 d8
+    call 00fdch                               ; e8 65 d8
     movzx ax, dl                              ; 0f b6 c2
-    call 03407h                               ; e8 9a fc
+    call 0340fh                               ; e8 92 fc
     mov ax, cx                                ; 89 c8
-    call 033d1h                               ; e8 5f fc
+    call 033d1h                               ; e8 4f fc
     mov ax, di                                ; 89 f8
-    call 033ech                               ; e8 75 fc
+    call 033f0h                               ; e8 69 fc
     xor ax, ax                                ; 31 c0
-    call 005e7h                               ; e8 6b ce
+    call 00603h                               ; e8 77 ce
     mov al, byte [bp-008h]                    ; 8a 46 f8
     or AL, strict byte 001h                   ; 0c 01
     movzx dx, al                              ; 0f b6 d0
     movzx ax, byte [bp-006h]                  ; 0f b6 46 fa
     or ax, dx                                 ; 09 d0
-    call 005c9h                               ; e8 3c ce
-    call 006c3h                               ; e8 33 cf
+    call 005ddh                               ; e8 40 ce
+    call 0070dh                               ; e8 6d cf
     mov bx, word [bp-00ah]                    ; 8b 5e f6
     mov dx, 000bah                            ; ba ba 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 02f68h                               ; e8 cc f7
+    call 02f68h                               ; e8 bc f7
     mov al, byte [bp-008h]                    ; 8a 46 f8
     or AL, strict byte 060h                   ; 0c 60
     movzx bx, al                              ; 0f b6 d8
     mov dx, 00087h                            ; ba 87 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 02f4ch                               ; e8 9f f7
-    jmp near 0371eh                           ; e9 6e ff
+    call 02f4ch                               ; e8 8f f7
+    jmp near 0372eh                           ; e9 6e ff
     mov ax, 00100h                            ; b8 00 01
     mov word [ss:si], ax                      ; 36 89 04
     lea sp, [bp-004h]                         ; 8d 66 fc
@@ -6424,13 +6435,13 @@ vbe_biosfn_set_mode_:                        ; 0xc36d4 LB 0xe9
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_biosfn_read_video_state_size_:           ; 0xc37bd LB 0x8
+vbe_biosfn_read_video_state_size_:           ; 0xc37cd LB 0x8
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     mov ax, strict word 00012h                ; b8 12 00
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_biosfn_save_video_state_:                ; 0xc37c5 LB 0x5b
+vbe_biosfn_save_video_state_:                ; 0xc37d5 LB 0x5b
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6449,17 +6460,17 @@ vbe_biosfn_save_video_state_:                ; 0xc37c5 LB 0x5b
     mov bx, ax                                ; 89 c3
     mov dx, cx                                ; 89 ca
     mov ax, di                                ; 89 f8
-    call 02f68h                               ; e8 80 f7
+    call 02f68h                               ; e8 70 f7
     inc cx                                    ; 41
     inc cx                                    ; 41
     test byte [bp-00ah], 001h                 ; f6 46 f6 01
-    je short 03817h                           ; 74 27
+    je short 03827h                           ; 74 27
     mov si, strict word 00001h                ; be 01 00
-    jmp short 037fah                          ; eb 05
+    jmp short 0380ah                          ; eb 05
     cmp si, strict byte 00009h                ; 83 fe 09
-    jnbe short 03817h                         ; 77 1d
+    jnbe short 03827h                         ; 77 1d
     cmp si, strict byte 00004h                ; 83 fe 04
-    je short 03814h                           ; 74 15
+    je short 03824h                           ; 74 15
     mov ax, si                                ; 89 f0
     mov dx, 001ceh                            ; ba ce 01
     out DX, ax                                ; ef
@@ -6468,11 +6479,11 @@ vbe_biosfn_save_video_state_:                ; 0xc37c5 LB 0x5b
     mov bx, ax                                ; 89 c3
     mov dx, cx                                ; 89 ca
     mov ax, di                                ; 89 f8
-    call 02f68h                               ; e8 56 f7
+    call 02f68h                               ; e8 46 f7
     inc cx                                    ; 41
     inc cx                                    ; 41
     inc si                                    ; 46
-    jmp short 037f5h                          ; eb de
+    jmp short 03805h                          ; eb de
     lea sp, [bp-008h]                         ; 8d 66 f8
     pop di                                    ; 5f
     pop si                                    ; 5e
@@ -6480,7 +6491,7 @@ vbe_biosfn_save_video_state_:                ; 0xc37c5 LB 0x5b
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_biosfn_restore_video_state_:             ; 0xc3820 LB 0x9b
+vbe_biosfn_restore_video_state_:             ; 0xc3830 LB 0x9b
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -6489,25 +6500,25 @@ vbe_biosfn_restore_video_state_:             ; 0xc3820 LB 0x9b
     push ax                                   ; 50
     mov cx, ax                                ; 89 c1
     mov bx, dx                                ; 89 d3
-    call 02f5ah                               ; e8 2c f7
+    call 02f5ah                               ; e8 1c f7
     mov word [bp-008h], ax                    ; 89 46 f8
     inc bx                                    ; 43
     inc bx                                    ; 43
     test byte [bp-008h], 001h                 ; f6 46 f8 01
-    jne short 03849h                          ; 75 10
+    jne short 03859h                          ; 75 10
     mov ax, strict word 00004h                ; b8 04 00
     mov dx, 001ceh                            ; ba ce 01
     out DX, ax                                ; ef
     mov ax, word [bp-008h]                    ; 8b 46 f8
     mov dx, 001cfh                            ; ba cf 01
     out DX, ax                                ; ef
-    jmp short 038b3h                          ; eb 6a
+    jmp short 038c3h                          ; eb 6a
     mov ax, strict word 00001h                ; b8 01 00
     mov dx, 001ceh                            ; ba ce 01
     out DX, ax                                ; ef
     mov dx, bx                                ; 89 da
     mov ax, cx                                ; 89 c8
-    call 02f5ah                               ; e8 03 f7
+    call 02f5ah                               ; e8 f3 f6
     mov dx, 001cfh                            ; ba cf 01
     out DX, ax                                ; ef
     inc bx                                    ; 43
@@ -6517,7 +6528,7 @@ vbe_biosfn_restore_video_state_:             ; 0xc3820 LB 0x9b
     out DX, ax                                ; ef
     mov dx, bx                                ; 89 da
     mov ax, cx                                ; 89 c8
-    call 02f5ah                               ; e8 ef f6
+    call 02f5ah                               ; e8 df f6
     mov dx, 001cfh                            ; ba cf 01
     out DX, ax                                ; ef
     inc bx                                    ; 43
@@ -6527,7 +6538,7 @@ vbe_biosfn_restore_video_state_:             ; 0xc3820 LB 0x9b
     out DX, ax                                ; ef
     mov dx, bx                                ; 89 da
     mov ax, cx                                ; 89 c8
-    call 02f5ah                               ; e8 db f6
+    call 02f5ah                               ; e8 cb f6
     mov dx, 001cfh                            ; ba cf 01
     out DX, ax                                ; ef
     inc bx                                    ; 43
@@ -6539,28 +6550,28 @@ vbe_biosfn_restore_video_state_:             ; 0xc3820 LB 0x9b
     mov dx, 001cfh                            ; ba cf 01
     out DX, ax                                ; ef
     mov si, strict word 00005h                ; be 05 00
-    jmp short 0389dh                          ; eb 05
+    jmp short 038adh                          ; eb 05
     cmp si, strict byte 00009h                ; 83 fe 09
-    jnbe short 038b3h                         ; 77 16
+    jnbe short 038c3h                         ; 77 16
     mov ax, si                                ; 89 f0
     mov dx, 001ceh                            ; ba ce 01
     out DX, ax                                ; ef
     mov dx, bx                                ; 89 da
     mov ax, cx                                ; 89 c8
-    call 02f5ah                               ; e8 b0 f6
+    call 02f5ah                               ; e8 a0 f6
     mov dx, 001cfh                            ; ba cf 01
     out DX, ax                                ; ef
     inc bx                                    ; 43
     inc bx                                    ; 43
     inc si                                    ; 46
-    jmp short 03898h                          ; eb e5
+    jmp short 038a8h                          ; eb e5
     lea sp, [bp-006h]                         ; 8d 66 fa
     pop si                                    ; 5e
     pop cx                                    ; 59
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-vbe_biosfn_save_restore_state_:              ; 0xc38bb LB 0x8c
+vbe_biosfn_save_restore_state_:              ; 0xc38cb LB 0x8c
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -6573,48 +6584,48 @@ vbe_biosfn_save_restore_state_:              ; 0xc38bb LB 0x8c
     mov di, strict word 0004fh                ; bf 4f 00
     xor ah, ah                                ; 30 e4
     cmp ax, strict word 00002h                ; 3d 02 00
-    je short 0391ah                           ; 74 45
+    je short 0392ah                           ; 74 45
     cmp ax, strict word 00001h                ; 3d 01 00
-    je short 038feh                           ; 74 24
+    je short 0390eh                           ; 74 24
     test ax, ax                               ; 85 c0
-    jne short 03936h                          ; 75 58
+    jne short 03946h                          ; 75 58
     mov ax, word [bp-006h]                    ; 8b 46 fa
-    call 02853h                               ; e8 6f ef
+    call 02853h                               ; e8 5f ef
     mov cx, ax                                ; 89 c1
     test byte [bp-006h], 008h                 ; f6 46 fa 08
-    je short 038f1h                           ; 74 05
-    call 037bdh                               ; e8 ce fe
+    je short 03901h                           ; 74 05
+    call 037cdh                               ; e8 ce fe
     add ax, cx                                ; 01 c8
     add ax, strict word 0003fh                ; 05 3f 00
     shr ax, 006h                              ; c1 e8 06
     push SS                                   ; 16
     pop ES                                    ; 07
     mov word [es:bx], ax                      ; 26 89 07
-    jmp short 03939h                          ; eb 3b
+    jmp short 03949h                          ; eb 3b
     push SS                                   ; 16
     pop ES                                    ; 07
     mov bx, word [es:bx]                      ; 26 8b 1f
     mov dx, cx                                ; 89 ca
     mov ax, word [bp-006h]                    ; 8b 46 fa
-    call 02888h                               ; e8 7d ef
+    call 02888h                               ; e8 6d ef
     test byte [bp-006h], 008h                 ; f6 46 fa 08
-    je short 03939h                           ; 74 28
+    je short 03949h                           ; 74 28
     mov dx, ax                                ; 89 c2
     mov ax, cx                                ; 89 c8
-    call 037c5h                               ; e8 ad fe
-    jmp short 03939h                          ; eb 1f
+    call 037d5h                               ; e8 ad fe
+    jmp short 03949h                          ; eb 1f
     push SS                                   ; 16
     pop ES                                    ; 07
     mov bx, word [es:bx]                      ; 26 8b 1f
     mov dx, cx                                ; 89 ca
     mov ax, word [bp-006h]                    ; 8b 46 fa
-    call 02bf1h                               ; e8 ca f2
+    call 02bf1h                               ; e8 ba f2
     test byte [bp-006h], 008h                 ; f6 46 fa 08
-    je short 03939h                           ; 74 0c
+    je short 03949h                           ; 74 0c
     mov dx, ax                                ; 89 c2
     mov ax, cx                                ; 89 c8
-    call 03820h                               ; e8 ec fe
-    jmp short 03939h                          ; eb 03
+    call 03830h                               ; e8 ec fe
+    jmp short 03949h                          ; eb 03
     mov di, 00100h                            ; bf 00 01
     push SS                                   ; 16
     pop ES                                    ; 07
@@ -6625,11 +6636,11 @@ vbe_biosfn_save_restore_state_:              ; 0xc38bb LB 0x8c
     pop bp                                    ; 5d
     retn 00002h                               ; c2 02 00
 
-  ; Padding 0xcb9 bytes at 0xc3947
-  times 3257 db 0
+  ; Padding 0xaa9 bytes at 0xc3957
+  times 2729 db 0
 
-section VBE32 progbits vstart=0x4600 align=1 ; size=0x115 class=CODE group=AUTO
-vesa_pm_start:                               ; 0xc4600 LB 0x114
+section VBE32 progbits vstart=0x4400 align=1 ; size=0x115 class=CODE group=AUTO
+vesa_pm_start:                               ; 0xc4400 LB 0x114
     sbb byte [bx+si], al                      ; 18 00
     dec di                                    ; 4f
     add byte [bx+si], dl                      ; 00 10
@@ -6660,20 +6671,20 @@ vesa_pm_start:                               ; 0xc4600 LB 0x114
     pop edx                                   ; 66 5a
     db  066h, 03bh, 0d0h
     ; cmp edx, eax                              ; 66 3b d0
-    jne short 0464ah                          ; 75 05
+    jne short 0444ah                          ; 75 05
     mov eax, strict dword 066c3004fh          ; 66 b8 4f 00 c3 66
     mov ax, 0014fh                            ; b8 4f 01
     retn                                      ; c3
     cmp bl, 080h                              ; 80 fb 80
-    je short 0465eh                           ; 74 0a
+    je short 0445eh                           ; 74 0a
     cmp bl, 000h                              ; 80 fb 00
-    je short 0466eh                           ; 74 15
+    je short 0446eh                           ; 74 15
     mov eax, strict dword 052c30100h          ; 66 b8 00 01 c3 52
     mov edx, strict dword 0a8ec03dah          ; 66 ba da 03 ec a8
     or byte [di-005h], dh                     ; 08 75 fb
     in AL, DX                                 ; ec
     test AL, strict byte 008h                 ; a8 08
-    je short 04668h                           ; 74 fb
+    je short 04468h                           ; 74 fb
     pop dx                                    ; 5a
     push ax                                   ; 50
     push cx                                   ; 51
@@ -6703,7 +6714,7 @@ vesa_pm_start:                               ; 0xc4600 LB 0x114
     ; movzx si, ax                              ; 0f b7 f0
     pop ax                                    ; 58
     cmp si, strict byte 00004h                ; 83 fe 04
-    je short 046c7h                           ; 74 17
+    je short 044c7h                           ; 74 17
     add si, strict byte 00007h                ; 83 c6 07
     shr si, 003h                              ; c1 ee 03
     imul cx, si                               ; 0f af ce
@@ -6717,7 +6728,7 @@ vesa_pm_start:                               ; 0xc4600 LB 0x114
     db  033h, 0d2h
     ; xor dx, dx                                ; 33 d2
     div si                                    ; f7 f6
-    jmp short 046d3h                          ; eb 0c
+    jmp short 044d3h                          ; eb 0c
     shr cx, 1                                 ; d1 e9
     db  033h, 0d2h
     ; xor dx, dx                                ; 33 d2
@@ -6752,16 +6763,16 @@ vesa_pm_start:                               ; 0xc4600 LB 0x114
     pop ax                                    ; 58
     mov eax, strict dword 066c3004fh          ; 66 b8 4f 00 c3 66
     mov ax, 0014fh                            ; b8 4f 01
-vesa_pm_end:                                 ; 0xc4714 LB 0x1
+vesa_pm_end:                                 ; 0xc4514 LB 0x1
     retn                                      ; c3
 
-  ; Padding 0xeb bytes at 0xc4715
+  ; Padding 0xeb bytes at 0xc4515
   times 235 db 0
 
-section _DATA progbits vstart=0x4800 align=1 ; size=0x36e1 class=DATA group=DGROUP
-_msg_vga_init:                               ; 0xc4800 LB 0x2f
-    db  'Oracle VM VirtualBox Version 4.3.53 VGA BIOS', 00dh, 00ah, 000h
-_vga_modes:                                  ; 0xc482f LB 0x80
+section _DATA progbits vstart=0x4600 align=1 ; size=0x372a class=DATA group=DGROUP
+_msg_vga_init:                               ; 0xc4600 LB 0x34
+    db  'Oracle VM VirtualBox Version 5.0.0_BETA2 VGA BIOS', 00dh, 00ah, 000h
+_vga_modes:                                  ; 0xc4634 LB 0x80
     db  000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
     db  002h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 003h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
     db  004h, 001h, 002h, 002h, 000h, 0b8h, 0ffh, 001h, 005h, 001h, 002h, 002h, 000h, 0b8h, 0ffh, 001h
@@ -6770,11 +6781,11 @@ _vga_modes:                                  ; 0xc482f LB 0x80
     db  00fh, 001h, 003h, 001h, 000h, 0a0h, 0ffh, 000h, 010h, 001h, 004h, 004h, 000h, 0a0h, 0ffh, 002h
     db  011h, 001h, 003h, 001h, 000h, 0a0h, 0ffh, 002h, 012h, 001h, 004h, 004h, 000h, 0a0h, 0ffh, 002h
     db  013h, 001h, 005h, 008h, 000h, 0a0h, 0ffh, 003h, 06ah, 001h, 004h, 004h, 000h, 0a0h, 0ffh, 002h
-_line_to_vpti:                               ; 0xc48af LB 0x10
+_line_to_vpti:                               ; 0xc46b4 LB 0x10
     db  017h, 017h, 018h, 018h, 004h, 005h, 006h, 007h, 00dh, 00eh, 011h, 012h, 01ah, 01bh, 01ch, 01dh
-_dac_regs:                                   ; 0xc48bf LB 0x4
+_dac_regs:                                   ; 0xc46c4 LB 0x4
     dd  0ff3f3f3fh
-_video_param_table:                          ; 0xc48c3 LB 0x780
+_video_param_table:                          ; 0xc46c8 LB 0x780
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
@@ -6895,7 +6906,7 @@ _video_param_table:                          ; 0xc48c3 LB 0x780
     db  072h, 0f0h, 000h, 060h, 000h, 000h, 000h, 000h, 000h, 000h, 059h, 08dh, 057h, 032h, 000h, 057h
     db  073h, 0e3h, 0ffh, 000h, 001h, 002h, 003h, 004h, 005h, 014h, 007h, 038h, 039h, 03ah, 03bh, 03ch
     db  03dh, 03eh, 03fh, 001h, 000h, 00fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 005h, 00fh, 0ffh
-_palette0:                                   ; 0xc5043 LB 0xc0
+_palette0:                                   ; 0xc4e48 LB 0xc0
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
@@ -6908,7 +6919,7 @@ _palette0:                                   ; 0xc5043 LB 0xc0
     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
     db  03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
-_palette1:                                   ; 0xc5103 LB 0xc0
+_palette1:                                   ; 0xc4f08 LB 0xc0
     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
     db  000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah
     db  000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah, 000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah
@@ -6921,7 +6932,7 @@ _palette1:                                   ; 0xc5103 LB 0xc0
     db  015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh, 015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh
     db  015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
-_palette2:                                   ; 0xc51c3 LB 0xc0
+_palette2:                                   ; 0xc4fc8 LB 0xc0
     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
     db  000h, 02ah, 02ah, 02ah, 000h, 02ah, 02ah, 02ah, 000h, 000h, 015h, 000h, 000h, 03fh, 000h, 02ah
     db  015h, 000h, 02ah, 03fh, 02ah, 000h, 015h, 02ah, 000h, 03fh, 02ah, 02ah, 015h, 02ah, 02ah, 03fh
@@ -6934,7 +6945,7 @@ _palette2:                                   ; 0xc51c3 LB 0xc0
     db  015h, 015h, 000h, 015h, 015h, 02ah, 015h, 03fh, 000h, 015h, 03fh, 02ah, 03fh, 015h, 000h, 03fh
     db  015h, 02ah, 03fh, 03fh, 000h, 03fh, 03fh, 02ah, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
-_palette3:                                   ; 0xc5283 LB 0x300
+_palette3:                                   ; 0xc5088 LB 0x300
     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
     db  000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
@@ -6983,12 +6994,19 @@ _palette3:                                   ; 0xc5283 LB 0x300
     db  00bh, 010h, 00bh, 00bh, 010h, 00ch, 00bh, 010h, 00dh, 00bh, 010h, 00fh, 00bh, 010h, 010h, 00bh
     db  00fh, 010h, 00bh, 00dh, 010h, 00bh, 00ch, 010h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_static_functionality:                       ; 0xc5583 LB 0x10
+_static_functionality:                       ; 0xc5388 LB 0x10
     db  0ffh, 0e0h, 00fh, 000h, 000h, 000h, 000h, 007h, 002h, 008h, 0e7h, 00ch, 000h, 000h, 000h, 000h
-_video_save_pointer_table:                   ; 0xc5593 LB 0x1c
-    db  0c3h, 048h, 000h, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_vgafont8:                                   ; 0xc55af LB 0x800
+_dcc_table:                                  ; 0xc5398 LB 0x24
+    db  010h, 001h, 007h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h
+_secondary_save_area:                        ; 0xc53bc LB 0x1a
+    db  01ah, 000h, 098h, 053h, 000h, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+_video_save_pointer_table:                   ; 0xc53d6 LB 0x1c
+    db  0c8h, 046h, 000h, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  0bch, 053h, 000h, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+_vgafont8:                                   ; 0xc53f2 LB 0x800
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07eh, 081h, 0a5h, 081h, 0bdh, 099h, 081h, 07eh
     db  07eh, 0ffh, 0dbh, 0ffh, 0c3h, 0e7h, 0ffh, 07eh, 06ch, 0feh, 0feh, 0feh, 07ch, 038h, 010h, 000h
     db  010h, 038h, 07ch, 0feh, 07ch, 038h, 010h, 000h, 038h, 07ch, 038h, 0feh, 0feh, 07ch, 038h, 07ch
@@ -7117,7 +7135,7 @@ _vgafont8:                                   ; 0xc55af LB 0x800
     db  000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h, 00fh, 00ch, 00ch, 00ch, 0ech, 06ch, 03ch, 01ch
     db  078h, 06ch, 06ch, 06ch, 06ch, 000h, 000h, 000h, 070h, 018h, 030h, 060h, 078h, 000h, 000h, 000h
     db  000h, 000h, 03ch, 03ch, 03ch, 03ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_vgafont14:                                  ; 0xc5daf LB 0xe00
+_vgafont14:                                  ; 0xc5bf2 LB 0xe00
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  07eh, 081h, 0a5h, 081h, 081h, 0bdh, 099h, 081h, 07eh, 000h, 000h, 000h, 000h, 000h, 07eh, 0ffh
     db  0dbh, 0ffh, 0ffh, 0c3h, 0e7h, 0ffh, 07eh, 000h, 000h, 000h, 000h, 000h, 000h, 06ch, 0feh, 0feh
@@ -7342,7 +7360,7 @@ _vgafont14:                                  ; 0xc5daf LB 0xe00
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 070h, 0d8h, 030h, 060h, 0c8h, 0f8h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_vgafont16:                                  ; 0xc6baf LB 0x1000
+_vgafont16:                                  ; 0xc69f2 LB 0x1000
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 07eh, 081h, 0a5h, 081h, 081h, 0bdh, 099h, 081h, 081h, 07eh, 000h, 000h, 000h, 000h
     db  000h, 000h, 07eh, 0ffh, 0dbh, 0ffh, 0ffh, 0c3h, 0e7h, 0ffh, 0ffh, 07eh, 000h, 000h, 000h, 000h
@@ -7599,7 +7617,7 @@ _vgafont16:                                  ; 0xc6baf LB 0x1000
     db  000h, 070h, 0d8h, 030h, 060h, 0c8h, 0f8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-_vgafont14alt:                               ; 0xc7baf LB 0x12d
+_vgafont14alt:                               ; 0xc79f2 LB 0x12d
     db  01dh, 000h, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h, 000h, 000h, 000h, 022h
     db  000h, 063h, 063h, 063h, 022h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 02bh, 000h
     db  000h, 000h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h, 000h, 000h, 000h, 000h, 02dh, 000h, 000h
@@ -7619,7 +7637,7 @@ _vgafont14alt:                               ; 0xc7baf LB 0x12d
     db  000h, 0fch, 066h, 066h, 07ch, 062h, 066h, 06fh, 066h, 066h, 0f3h, 000h, 000h, 000h, 0f1h, 000h
     db  000h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h, 000h, 0ffh, 000h, 000h, 000h, 0f6h, 000h, 000h
     db  018h, 018h, 000h, 000h, 0ffh, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h
-_vgafont16alt:                               ; 0xc7cdc LB 0x144
+_vgafont16alt:                               ; 0xc7b1f LB 0x145
     db  01dh, 000h, 000h, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h, 000h, 000h, 000h
     db  000h, 030h, 000h, 000h, 03ch, 066h, 0c3h, 0c3h, 0dbh, 0dbh, 0c3h, 0c3h, 066h, 03ch, 000h, 000h
     db  000h, 000h, 04dh, 000h, 000h, 0c3h, 0e7h, 0ffh, 0ffh, 0dbh, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 000h
@@ -7640,34 +7658,59 @@ _vgafont16alt:                               ; 0xc7cdc LB 0x144
     db  09eh, 000h, 0fch, 066h, 066h, 07ch, 062h, 066h, 06fh, 066h, 066h, 066h, 0f3h, 000h, 000h, 000h
     db  000h, 0abh, 000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 060h, 0ceh, 09bh, 006h, 00ch, 01fh
     db  000h, 000h, 0ach, 000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 066h, 0ceh, 096h, 03eh, 006h
-    db  006h, 000h, 000h, 000h
-_vbebios_copyright:                          ; 0xc7e20 LB 0x15
+    db  006h, 000h, 000h, 000h, 000h
+_vbebios_copyright:                          ; 0xc7c64 LB 0x15
     db  'VirtualBox VESA BIOS', 000h
-_vbebios_vendor_name:                        ; 0xc7e35 LB 0x13
+_vbebios_vendor_name:                        ; 0xc7c79 LB 0x13
     db  'Oracle Corporation', 000h
-_vbebios_product_name:                       ; 0xc7e48 LB 0x21
+_vbebios_product_name:                       ; 0xc7c8c LB 0x21
     db  'Oracle VM VirtualBox VBE Adapter', 000h
-_vbebios_product_revision:                   ; 0xc7e69 LB 0x24
-    db  'Oracle VM VirtualBox Version 4.3.53', 000h
-_vbebios_info_string:                        ; 0xc7e8d LB 0x2b
+_vbebios_product_revision:                   ; 0xc7cad LB 0x29
+    db  'Oracle VM VirtualBox Version 5.0.0_BETA2', 000h
+_vbebios_info_string:                        ; 0xc7cd6 LB 0x2b
     db  'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
-_no_vbebios_info_string:                     ; 0xc7eb8 LB 0x29
+_no_vbebios_info_string:                     ; 0xc7d01 LB 0x29
     db  'No VirtualBox VBE support available!', 00dh, 00ah, 00dh, 00ah, 000h
 
-  ; Padding 0x1 bytes at 0xc7ee1
-    db  001h
-
-section CONST progbits vstart=0x7ee2 align=1 ; size=0x0 class=DATA group=DGROUP
+section CONST progbits vstart=0x7d2a align=1 ; size=0x0 class=DATA group=DGROUP
 
-section CONST2 progbits vstart=0x7ee2 align=1 ; size=0x0 class=DATA group=DGROUP
+section CONST2 progbits vstart=0x7d2a align=1 ; size=0x0 class=DATA group=DGROUP
 
-  ; Padding 0x11e bytes at 0xc7ee2
-    db  000h, 000h, 000h, 000h, 001h, 000h, 000h, 000h, 000h, 000h, 000h, 02fh, 068h, 06fh, 06dh, 065h
-    db  02fh, 066h, 06dh, 033h, 02fh, 073h, 072h, 063h, 02fh, 076h, 062h, 06fh, 078h, 02fh, 06fh, 075h
-    db  074h, 02fh, 06ch, 069h, 06eh, 075h, 078h, 02eh, 061h, 06dh, 064h, 036h, 034h, 02fh, 072h, 065h
-    db  06ch, 065h, 061h, 073h, 065h, 02fh, 06fh, 062h, 06ah, 02fh, 056h, 042h, 06fh, 078h, 056h, 067h
-    db  061h, 042h, 069h, 06fh, 073h, 02fh, 056h, 042h, 06fh, 078h, 056h, 067h, 061h, 042h, 069h, 06fh
-    db  073h, 02eh, 073h, 079h, 06dh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+  ; Padding 0x2d6 bytes at 0xc7d2a
+    db  001h, 000h, 000h, 000h, 000h, 001h, 000h, 000h, 000h, 000h, 000h, 000h, 02fh, 068h, 06fh, 06dh
+    db  065h, 02fh, 066h, 06dh, 033h, 02fh, 073h, 072h, 063h, 02fh, 076h, 062h, 06fh, 078h, 02fh, 06fh
+    db  075h, 074h, 02fh, 06ch, 069h, 06eh, 075h, 078h, 02eh, 061h, 06dh, 064h, 036h, 034h, 02fh, 072h
+    db  065h, 06ch, 065h, 061h, 073h, 065h, 02fh, 06fh, 062h, 06ah, 02fh, 056h, 042h, 06fh, 078h, 056h
+    db  067h, 061h, 042h, 069h, 06fh, 073h, 02fh, 056h, 042h, 06fh, 078h, 056h, 067h, 061h, 042h, 069h
+    db  06fh, 073h, 02eh, 073h, 079h, 06dh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
@@ -7679,4 +7722,4 @@ section CONST2 progbits vstart=0x7ee2 align=1 ; size=0x0 class=DATA group=DGROUP
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
-    db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 055h
+    db  000h, 000h, 000h, 000h, 000h, 0e0h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
index 106f880..d9bc6e8 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
@@ -1 +1 @@
-2abf7b9050be07a06bb5f956042ff4df *VBoxVgaBios.rom
+7e4d004d15d19ad5f6d812e04876154c *VBoxVgaBios.rom
diff --git a/src/VBox/Devices/Input/PS2M.cpp b/src/VBox/Devices/Input/PS2M.cpp
index 191c7ef..329b8fc 100644
--- a/src/VBox/Devices/Input/PS2M.cpp
+++ b/src/VBox/Devices/Input/PS2M.cpp
@@ -543,7 +543,7 @@ static void ps2mReportAccumulatedEvents(PPS2M pThis, GeneriQ *pQueue, bool fAccu
             /* Z value uses 4 bits; buttons 4/5 in bits 4 and 5. */
             val  = dZ & 0x0f;
             val |= (fBtnState << 1) & (RT_BIT(4) | RT_BIT(5));
-            ps2kInsertQueue(pQueue, dZ);
+            ps2kInsertQueue(pQueue, val);
         }
     }
 
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index 63f2718..7659474 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -177,6 +177,7 @@ if !defined(VBOX_ONLY_EXTPACKS)         # Goes on almost to the end of the file.
  	PC/DrvAcpiCpu.cpp \
  	Serial/DrvChar.cpp \
  	Serial/DrvNamedPipe.cpp \
+ 	Serial/DrvTCP.cpp \
  	Serial/DrvRawFile.cpp \
  	Storage/DrvBlock.cpp \
  	Storage/DrvMediaISO.cpp \
diff --git a/src/VBox/Devices/Network/slirp/bsd/sys/mbuf.h b/src/VBox/Devices/Network/slirp/bsd/sys/mbuf.h
index 57c5f57..ca576d2 100644
--- a/src/VBox/Devices/Network/slirp/bsd/sys/mbuf.h
+++ b/src/VBox/Devices/Network/slirp/bsd/sys/mbuf.h
@@ -60,7 +60,7 @@ DECLNORETURN(static void) panic (char *fmt, ...)
     AssertFatalFailed();
 }
 /* for non-gnu compilers */
-# define __func__ __FUNCTION__
+# define __func__ RT_GCC_EXTENSION __FUNCTION__
 # ifndef __inline
 #  define __inline
 # endif
diff --git a/src/VBox/Devices/Network/slirp/resolv_conf_parser.c b/src/VBox/Devices/Network/slirp/resolv_conf_parser.c
index 647d705..91c71e0 100644
--- a/src/VBox/Devices/Network/slirp/resolv_conf_parser.c
+++ b/src/VBox/Devices/Network/slirp/resolv_conf_parser.c
@@ -22,6 +22,10 @@
 #include <iprt/stream.h>
 #include <iprt/thread.h>
 
+#ifdef RT_OS_FREEBSD
+# include <sys/socket.h>
+#endif
+
 #include <arpa/inet.h>
 
 #include <ctype.h>
diff --git a/src/VBox/Devices/Network/slirp/slirp_dns.c b/src/VBox/Devices/Network/slirp/slirp_dns.c
index d82bda9..626a1d4 100644
--- a/src/VBox/Devices/Network/slirp/slirp_dns.c
+++ b/src/VBox/Devices/Network/slirp/slirp_dns.c
@@ -217,7 +217,7 @@ static int get_dns_addr_domain(PNATState pData, const char **ppszDomain)
         }
 
         pDomain->dd_pszDomain = RTStrDup(st.rcps_domain);
-        LogRel(("NAT: adding domain name %s\n", pDomain->dd_pszDomain));
+        LogRel(("NAT: Adding domain name %s\n", pDomain->dd_pszDomain));
         LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
     }
 
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
index fa211bf..febccb0 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
@@ -855,12 +855,12 @@ _fd_parm:                                    ; 0xf0000 LB 0x5b
 _fd_map:                                     ; 0xf005b LB 0xf
     db  001h, 000h, 002h, 002h, 003h, 003h, 004h, 004h, 005h, 005h, 00eh, 006h, 00fh, 006h, 000h
 _pktacc:                                     ; 0xf006a LB 0xc
-    db  000h, 000h, 000h, 000h, 000h, 000h, 08fh, 028h, 05dh, 07bh, 025h, 089h
+    db  000h, 000h, 000h, 000h, 000h, 000h, 08fh, 028h, 089h, 07bh, 06bh, 089h
 _softrst:                                    ; 0xf0076 LB 0xc
     db  000h, 000h, 000h, 000h, 000h, 000h, 077h, 02bh, 054h, 038h, 054h, 038h
 _dskacc:                                     ; 0xf0082 LB 0x2e
     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0d8h, 027h, 052h, 028h, 000h, 000h, 000h, 000h
-    db  0ebh, 079h, 0a4h, 07ah, 021h, 088h, 0b5h, 088h, 000h, 000h, 000h, 000h, 000h, 000h, 05fh, 033h
+    db  017h, 07ah, 0d0h, 07ah, 066h, 088h, 0f9h, 088h, 000h, 000h, 000h, 000h, 000h, 000h, 05fh, 033h
     db  032h, 05fh, 000h, 0dah, 00fh, 000h, 000h, 001h, 0f3h, 000h, 000h, 000h, 000h, 000h
 
 section CONST progbits vstart=0xb0 align=1 ; size=0xce0 class=DATA group=DGROUP
@@ -983,7 +983,7 @@ section CONST progbits vstart=0xb0 align=1 ; size=0xce0 class=DATA group=DGROUP
 
 section CONST2 progbits vstart=0xd90 align=1 ; size=0x400 class=DATA group=DGROUP
 _bios_cvs_version_string:                    ; 0xf0d90 LB 0x18
-    db  'VirtualBox 5.0.0_BETA1', 000h, 000h
+    db  'VirtualBox 5.0.0_BETA2', 000h, 000h
 _bios_prefix_string:                         ; 0xf0da8 LB 0x8
     db  'BIOS: ', 000h, 000h
 _isotag:                                     ; 0xf0db0 LB 0x6
@@ -1057,7 +1057,7 @@ _panic_msg_keyb_buffer_full:                 ; 0xf1170 LB 0x20
   ; Padding 0x470 bytes at 0xf1190
   times 1136 db 0
 
-section _TEXT progbits vstart=0x1600 align=1 ; size=0x81e5 class=CODE group=AUTO
+section _TEXT progbits vstart=0x1600 align=1 ; size=0x8235 class=CODE group=AUTO
 rom_scan_:                                   ; 0xf1600 LB 0x50
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
@@ -1454,7 +1454,7 @@ put_luint_:                                  ; 0xf18bf LB 0x72
     mov dx, cx                                ; 89 ca
     mov bx, strict word 0000ah                ; bb 0a 00
     xor cx, cx                                ; 31 c9
-    call 096f0h                               ; e8 17 7e
+    call 09740h                               ; e8 67 7e
     mov word [bp-008h], ax                    ; 89 46 f8
     mov cx, dx                                ; 89 d1
     mov dx, ax                                ; 89 c2
@@ -4984,7 +4984,7 @@ cdrom_boot_:                                 ; 0xf3a5d LB 0x416
     xor bx, bx                                ; 31 db
     mov dx, ss                                ; 8c d2
     lea ax, [bp-026h]                         ; 8d 46 da
-    call 0975ah                               ; e8 a4 5c
+    call 097aah                               ; e8 f4 5c
     mov word [bp-026h], strict word 00028h    ; c7 46 da 28 00
     mov ax, strict word 00011h                ; b8 11 00
     xor dx, dx                                ; 31 d2
@@ -5443,13 +5443,13 @@ _int13_cdemu:                                ; 0xf3e73 LB 0x434
     mov word [bp-01ch], dx                    ; 89 56 e4
     xor dl, dl                                ; 30 d2
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 12 57
+    call 09779h                               ; e8 62 57
     xor bx, bx                                ; 31 db
     add ax, si                                ; 01 f0
     adc dx, bx                                ; 11 da
     mov bx, di                                ; 89 fb
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 05 57
+    call 09779h                               ; e8 55 57
     mov bx, ax                                ; 89 c3
     mov ax, word [bp-010h]                    ; 8b 46 f0
     dec ax                                    ; 48
@@ -5484,7 +5484,7 @@ _int13_cdemu:                                ; 0xf3e73 LB 0x434
     mov cx, strict word 0000ch                ; b9 0c 00
     mov dx, ss                                ; 8c d2
     lea ax, [bp-02eh]                         ; 8d 46 d2
-    call 0975ah                               ; e8 df 56
+    call 097aah                               ; e8 2f 57
     mov word [bp-02eh], strict word 00028h    ; c7 46 d2 28 00
     mov ax, word [bp-014h]                    ; 8b 46 ec
     add ax, si                                ; 01 f0
@@ -5791,7 +5791,7 @@ _int13_cdrom:                                ; 0xf42a7 LB 0x562
     xor bx, bx                                ; 31 db
     mov dx, ss                                ; 8c d2
     lea ax, [bp-02ch]                         ; 8d 46 d4
-    call 0975ah                               ; e8 44 53
+    call 097aah                               ; e8 94 53
     mov word [bp-02ch], strict word 00028h    ; c7 46 d4 28 00
     mov ax, word [bp-018h]                    ; 8b 46 e8
     mov dx, di                                ; 89 fa
@@ -7611,12 +7611,12 @@ set_geom_lba_:                               ; 0xf55b6 LB 0x9e
     xor dx, dx                                ; 31 d2
     mov bx, strict word 0003fh                ; bb 3f 00
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 30 41
+    call 09779h                               ; e8 80 41
     mov bx, ax                                ; 89 c3
     mov cx, dx                                ; 89 d1
     mov ax, word [bp-004h]                    ; 8b 46 fc
     mov dx, word [bp-002h]                    ; 8b 56 fe
-    call 096f0h                               ; e8 ea 40
+    call 09740h                               ; e8 3a 41
     mov word [es:si+002h], ax                 ; 26 89 44 02
     cmp ax, 00400h                            ; 3d 00 04
     jbe short 05615h                          ; 76 06
@@ -7834,13 +7834,13 @@ _int13_harddisk:                             ; 0xf5654 LB 0x441
     xor dx, dx                                ; 31 d2
     mov bx, cx                                ; 89 cb
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 05 3f
+    call 09779h                               ; e8 55 3f
     xor bx, bx                                ; 31 db
     add ax, word [bp-008h]                    ; 03 46 f8
     adc dx, bx                                ; 11 da
     mov bx, word [bp-00ah]                    ; 8b 5e f6
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 f6 3e
+    call 09779h                               ; e8 46 3f
     xor bx, bx                                ; 31 db
     add ax, word [bp-006h]                    ; 03 46 fa
     adc dx, bx                                ; 11 da
@@ -7998,10 +7998,10 @@ _int13_harddisk:                             ; 0xf5654 LB 0x441
     xor dx, dx                                ; 31 d2
     mov bx, word [bp-008h]                    ; 8b 5e f8
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 37 3d
+    call 09779h                               ; e8 87 3d
     mov bx, word [bp-006h]                    ; 8b 5e fa
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 2f 3d
+    call 09779h                               ; e8 7f 3d
     mov word [bp-010h], ax                    ; 89 46 f0
     mov word [bp-00eh], dx                    ; 89 56 f2
     mov word [bp+014h], dx                    ; 89 56 14
@@ -11048,7 +11048,7 @@ delay_boot_:                                 ; 0xf781e LB 0x67
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-scsi_cmd_data_in_:                           ; 0xf7885 LB 0xb2
+scsi_cmd_data_in_:                           ; 0xf7885 LB 0xc9
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -11056,8 +11056,8 @@ scsi_cmd_data_in_:                           ; 0xf7885 LB 0xb2
     sub sp, strict byte 00006h                ; 83 ec 06
     mov si, ax                                ; 89 c6
     mov byte [bp-006h], dl                    ; 88 56 fa
-    mov word [bp-00ah], bx                    ; 89 5e f6
-    mov word [bp-008h], cx                    ; 89 4e f8
+    mov word [bp-008h], bx                    ; 89 5e f8
+    mov word [bp-00ah], cx                    ; 89 4e f6
     mov bx, word [bp+00ah]                    ; 8b 5e 0a
     mov dx, si                                ; 89 f2
     in AL, DX                                 ; ec
@@ -11094,25 +11094,36 @@ scsi_cmd_data_in_:                           ; 0xf7885 LB 0xb2
     xor cx, cx                                ; 31 c9
     movzx ax, byte [bp+004h]                  ; 0f b6 46 04
     cmp cx, ax                                ; 39 c1
-    jnc short 078f3h                          ; 73 0e
-    les di, [bp-00ah]                         ; c4 7e f6
+    jnc short 078f6h                          ; 73 11
+    mov es, [bp-00ah]                         ; 8e 46 f6
+    mov di, word [bp-008h]                    ; 8b 7e f8
     add di, cx                                ; 01 cf
     mov al, byte [es:di]                      ; 26 8a 05
     mov dx, si                                ; 89 f2
     out DX, AL                                ; ee
     inc cx                                    ; 41
-    jmp short 078ddh                          ; eb ea
+    jmp short 078ddh                          ; eb e7
     mov dx, si                                ; 89 f2
     in AL, DX                                 ; ec
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     test AL, strict byte 001h                 ; a8 01
-    jne short 078f3h                          ; 75 f7
+    jne short 078f6h                          ; 75 f7
+    test AL, strict byte 002h                 ; a8 02
+    je short 07911h                           ; 74 0e
+    lea dx, [si+003h]                         ; 8d 54 03
+    xor al, al                                ; 30 c0
+    out DX, AL                                ; ee
+    in AL, DX                                 ; ec
+    db  02ah, 0e4h
+    ; sub ah, ah                                ; 2a e4
+    mov di, strict word 00004h                ; bf 04 00
+    jmp short 07943h                          ; eb 32
     lea dx, [si+001h]                         ; 8d 54 01
     cmp word [bp+00ch], strict byte 00000h    ; 83 7e 0c 00
-    jne short 0790bh                          ; 75 06
+    jne short 07920h                          ; 75 06
     cmp bx, 08000h                            ; 81 fb 00 80
-    jbe short 07925h                          ; 76 1a
+    jbe short 0793ah                          ; 76 1a
     mov cx, 08000h                            ; b9 00 80
     les di, [bp+006h]                         ; c4 7e 06
     rep insb                                  ; f3 6c
@@ -11121,17 +11132,18 @@ scsi_cmd_data_in_:                           ; 0xf7885 LB 0xb2
     mov ax, es                                ; 8c c0
     add ax, 00800h                            ; 05 00 08
     mov word [bp+008h], ax                    ; 89 46 08
-    jmp short 078fch                          ; eb d7
+    jmp short 07911h                          ; eb d7
     mov cx, bx                                ; 89 d9
     les di, [bp+006h]                         ; c4 7e 06
     rep insb                                  ; f3 6c
-    xor ax, ax                                ; 31 c0
+    xor di, di                                ; 31 ff
+    mov ax, di                                ; 89 f8
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 0000ah                               ; c2 0a 00
-scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
+scsi_cmd_data_out_:                          ; 0xf794e LB 0xc9
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -11139,21 +11151,21 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     sub sp, strict byte 00006h                ; 83 ec 06
     mov di, ax                                ; 89 c7
     mov byte [bp-006h], dl                    ; 88 56 fa
-    mov word [bp-00ah], bx                    ; 89 5e f6
-    mov word [bp-008h], cx                    ; 89 4e f8
+    mov word [bp-008h], bx                    ; 89 5e f8
+    mov word [bp-00ah], cx                    ; 89 4e f6
     mov bx, word [bp+00ah]                    ; 8b 5e 0a
     mov dx, di                                ; 89 fa
     in AL, DX                                 ; ec
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     test AL, strict byte 001h                 ; a8 01
-    jne short 0794dh                          ; 75 f7
+    jne short 07964h                          ; 75 f7
     mov ax, bx                                ; 89 d8
     mov dx, word [bp+00ch]                    ; 8b 56 0c
     mov cx, strict word 0000ch                ; b9 0c 00
     shr dx, 1                                 ; d1 ea
     rcr ax, 1                                 ; d1 d8
-    loop 0795eh                               ; e2 fa
+    loop 07975h                               ; e2 fa
     and ax, 000f0h                            ; 25 f0 00
     movzx cx, byte [bp+004h]                  ; 0f b6 4e 04
     or cx, ax                                 ; 09 c1
@@ -11171,25 +11183,26 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     mov cx, strict word 00008h                ; b9 08 00
     shr dx, 1                                 ; d1 ea
     rcr ax, 1                                 ; d1 d8
-    loop 07984h                               ; e2 fa
+    loop 0799bh                               ; e2 fa
     mov dx, di                                ; 89 fa
     out DX, AL                                ; ee
     xor cx, cx                                ; 31 c9
     movzx ax, byte [bp+004h]                  ; 0f b6 46 04
     cmp cx, ax                                ; 39 c1
-    jnc short 079a5h                          ; 73 0e
-    les si, [bp-00ah]                         ; c4 76 f6
+    jnc short 079bfh                          ; 73 11
+    mov es, [bp-00ah]                         ; 8e 46 f6
+    mov si, word [bp-008h]                    ; 8b 76 f8
     add si, cx                                ; 01 ce
     mov al, byte [es:si]                      ; 26 8a 04
     mov dx, di                                ; 89 fa
     out DX, AL                                ; ee
     inc cx                                    ; 41
-    jmp short 0798fh                          ; eb ea
+    jmp short 079a6h                          ; eb e7
     lea dx, [di+001h]                         ; 8d 55 01
     cmp word [bp+00ch], strict byte 00000h    ; 83 7e 0c 00
-    jne short 079b4h                          ; 75 06
+    jne short 079ceh                          ; 75 06
     cmp bx, 08000h                            ; 81 fb 00 80
-    jbe short 079cfh                          ; 76 1b
+    jbe short 079e9h                          ; 76 1b
     mov cx, 08000h                            ; b9 00 80
     les si, [bp+006h]                         ; c4 76 06
     db  0f3h, 026h, 06eh
@@ -11199,7 +11212,7 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     mov ax, es                                ; 8c c0
     add ax, 00800h                            ; 05 00 08
     mov word [bp+008h], ax                    ; 89 46 08
-    jmp short 079a5h                          ; eb d6
+    jmp short 079bfh                          ; eb d6
     mov cx, bx                                ; 89 d9
     les si, [bp+006h]                         ; c4 76 06
     db  0f3h, 026h, 06eh
@@ -11209,14 +11222,24 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     test AL, strict byte 001h                 ; a8 01
-    jne short 079d7h                          ; 75 f7
+    jne short 079f1h                          ; 75 f7
+    test AL, strict byte 002h                 ; a8 02
+    je short 07a0ch                           ; 74 0e
+    lea dx, [di+003h]                         ; 8d 55 03
+    xor al, al                                ; 30 c0
+    out DX, AL                                ; ee
+    in AL, DX                                 ; ec
+    db  02ah, 0e4h
+    ; sub ah, ah                                ; 2a e4
+    mov ax, strict word 00004h                ; b8 04 00
+    jmp short 07a0eh                          ; eb 02
     xor ax, ax                                ; 31 c0
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 0000ah                               ; c2 0a 00
- at scsi_read_sectors:                          ; 0xf79eb LB 0xb9
+ at scsi_read_sectors:                          ; 0xf7a17 LB 0xb9
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -11227,13 +11250,13 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     mov bl, byte [es:si+008h]                 ; 26 8a 5c 08
     sub bl, 008h                              ; 80 eb 08
     cmp bl, 004h                              ; 80 fb 04
-    jbe short 07a17h                          ; 76 12
+    jbe short 07a43h                          ; 76 12
     movzx ax, bl                              ; 0f b6 c3
     push ax                                   ; 50
     push 00b26h                               ; 68 26 0b
     push 00b38h                               ; 68 38 0b
     push strict byte 00007h                   ; 6a 07
-    call 01972h                               ; e8 5e 9f
+    call 01972h                               ; e8 32 9f
     add sp, strict byte 00008h                ; 83 c4 08
     mov es, [bp+006h]                         ; 8e 46 06
     mov di, word [es:si+00ah]                 ; 26 8b 7c 0a
@@ -11260,7 +11283,7 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     mov cx, strict word 00009h                ; b9 09 00
     sal word [bp-008h], 1                     ; d1 66 f8
     rcl word [bp-006h], 1                     ; d1 56 fa
-    loop 07a60h                               ; e2 f8
+    loop 07a8ch                               ; e2 f8
     push dword [bp-008h]                      ; 66 ff 76 f8
     db  066h, 026h, 0ffh, 074h, 004h
     ; push dword [es:si+004h]                   ; 66 26 ff 74 04
@@ -11268,10 +11291,10 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     xor dh, dh                                ; 30 f6
     mov cx, ss                                ; 8c d1
     lea bx, [bp-012h]                         ; 8d 5e ee
-    call 07885h                               ; e8 08 fe
+    call 07885h                               ; e8 dc fd
     mov ah, al                                ; 88 c4
     test al, al                               ; 84 c0
-    jne short 07a98h                          ; 75 15
+    jne short 07ac4h                          ; 75 15
     mov es, [bp+006h]                         ; 8e 46 06
     mov word [es:si+014h], di                 ; 26 89 7c 14
     mov dx, word [bp-008h]                    ; 8b 56 f8
@@ -11284,7 +11307,7 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 00004h                               ; c2 04 00
- at scsi_write_sectors:                         ; 0xf7aa4 LB 0xb9
+ at scsi_write_sectors:                         ; 0xf7ad0 LB 0xb9
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -11295,13 +11318,13 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     mov bl, byte [es:si+008h]                 ; 26 8a 5c 08
     sub bl, 008h                              ; 80 eb 08
     cmp bl, 004h                              ; 80 fb 04
-    jbe short 07ad0h                          ; 76 12
+    jbe short 07afch                          ; 76 12
     movzx ax, bl                              ; 0f b6 c3
     push ax                                   ; 50
     push 00b57h                               ; 68 57 0b
     push 00b38h                               ; 68 38 0b
     push strict byte 00007h                   ; 6a 07
-    call 01972h                               ; e8 a5 9e
+    call 01972h                               ; e8 79 9e
     add sp, strict byte 00008h                ; 83 c4 08
     mov es, [bp+006h]                         ; 8e 46 06
     mov di, word [es:si+00ah]                 ; 26 8b 7c 0a
@@ -11328,7 +11351,7 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     mov cx, strict word 00009h                ; b9 09 00
     sal word [bp-008h], 1                     ; d1 66 f8
     rcl word [bp-006h], 1                     ; d1 56 fa
-    loop 07b19h                               ; e2 f8
+    loop 07b45h                               ; e2 f8
     push dword [bp-008h]                      ; 66 ff 76 f8
     db  066h, 026h, 0ffh, 074h, 004h
     ; push dword [es:si+004h]                   ; 66 26 ff 74 04
@@ -11336,10 +11359,10 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     xor dh, dh                                ; 30 f6
     mov cx, ss                                ; 8c d1
     lea bx, [bp-012h]                         ; 8d 5e ee
-    call 07937h                               ; e8 01 fe
+    call 0794eh                               ; e8 ec fd
     mov ah, al                                ; 88 c4
     test al, al                               ; 84 c0
-    jne short 07b51h                          ; 75 15
+    jne short 07b7dh                          ; 75 15
     mov es, [bp+006h]                         ; 8e 46 06
     mov word [es:si+014h], di                 ; 26 89 7c 14
     mov dx, word [bp-008h]                    ; 8b 56 f8
@@ -11352,7 +11375,7 @@ scsi_cmd_data_out_:                          ; 0xf7937 LB 0xb4
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 00004h                               ; c2 04 00
-scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
+scsi_cmd_packet_:                            ; 0xf7b89 LB 0x166
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -11364,22 +11387,22 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     mov word [bp-00ah], cx                    ; 89 4e f6
     mov dx, strict word 0000eh                ; ba 0e 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0166ch                               ; e8 f3 9a
+    call 0166ch                               ; e8 c7 9a
     mov si, 00122h                            ; be 22 01
     mov word [bp-00eh], ax                    ; 89 46 f2
     cmp byte [bp+00ah], 002h                  ; 80 7e 0a 02
-    jne short 07ba4h                          ; 75 1f
+    jne short 07bd0h                          ; 75 1f
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 a1 9d
+    call 01931h                               ; e8 75 9d
     push 00b6ah                               ; 68 6a 0b
     push 00b7ah                               ; 68 7a 0b
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 d7 9d
+    call 01972h                               ; e8 ab 9d
     add sp, strict byte 00006h                ; 83 c4 06
     mov dx, strict word 00001h                ; ba 01 00
-    jmp near 07cb8h                           ; e9 14 01
+    jmp near 07ce4h                           ; e9 14 01
     sub di, strict byte 00008h                ; 83 ef 08
     sal di, 002h                              ; c1 e7 02
     sub byte [bp-006h], 002h                  ; 80 6e fa 02
@@ -11393,7 +11416,7 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     test AL, strict byte 001h                 ; a8 01
-    jne short 07bc0h                          ; 75 f7
+    jne short 07bech                          ; 75 f7
     xor ax, ax                                ; 31 c0
     mov dx, word [bp+006h]                    ; 8b 56 06
     add dx, word [bp+004h]                    ; 03 56 04
@@ -11409,7 +11432,7 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     mov cx, strict word 0000ch                ; b9 0c 00
     shr dx, 1                                 ; d1 ea
     rcr ax, 1                                 ; d1 d8
-    loop 07bebh                               ; e2 fa
+    loop 07c17h                               ; e2 fa
     and ax, 000f0h                            ; 25 f0 00
     movzx cx, byte [bp-006h]                  ; 0f b6 4e fa
     or cx, ax                                 ; 09 c1
@@ -11427,28 +11450,28 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     mov cx, strict word 00008h                ; b9 08 00
     shr dx, 1                                 ; d1 ea
     rcr ax, 1                                 ; d1 d8
-    loop 07c12h                               ; e2 fa
+    loop 07c3eh                               ; e2 fa
     mov dx, bx                                ; 89 da
     out DX, AL                                ; ee
     xor cx, cx                                ; 31 c9
     movzx ax, byte [bp-006h]                  ; 0f b6 46 fa
     cmp cx, ax                                ; 39 c1
-    jnc short 07c33h                          ; 73 0e
+    jnc short 07c5fh                          ; 73 0e
     les di, [bp-00ch]                         ; c4 7e f4
     add di, cx                                ; 01 cf
     mov al, byte [es:di]                      ; 26 8a 05
     mov dx, bx                                ; 89 da
     out DX, AL                                ; ee
     inc cx                                    ; 41
-    jmp short 07c1dh                          ; eb ea
+    jmp short 07c49h                          ; eb ea
     mov dx, bx                                ; 89 da
     in AL, DX                                 ; ec
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     test AL, strict byte 001h                 ; a8 01
-    jne short 07c33h                          ; 75 f7
+    jne short 07c5fh                          ; 75 f7
     test AL, strict byte 002h                 ; a8 02
-    je short 07c4eh                           ; 74 0e
+    je short 07c7ah                           ; 74 0e
     lea dx, [bx+003h]                         ; 8d 57 03
     xor al, al                                ; 30 c0
     out DX, AL                                ; ee
@@ -11456,14 +11479,14 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     mov dx, strict word 00003h                ; ba 03 00
-    jmp short 07cb8h                          ; eb 6a
+    jmp short 07ce4h                          ; eb 6a
     mov ax, word [bp+004h]                    ; 8b 46 04
     test ax, ax                               ; 85 c0
-    je short 07c5dh                           ; 74 08
+    je short 07c89h                           ; 74 08
     lea dx, [bx+001h]                         ; 8d 57 01
     mov cx, ax                                ; 89 c1
     in AL, DX                                 ; ec
-    loop 07c5ah                               ; e2 fd
+    loop 07c86h                               ; e2 fd
     mov ax, word [bp+006h]                    ; 8b 46 06
     mov es, [bp-00eh]                         ; 8e 46 f2
     mov word [es:si+016h], ax                 ; 26 89 44 16
@@ -11471,9 +11494,9 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     mov word [es:si+018h], ax                 ; 26 89 44 18
     lea ax, [bx+001h]                         ; 8d 47 01
     cmp word [bp+008h], strict byte 00000h    ; 83 7e 08 00
-    jne short 07c7eh                          ; 75 07
+    jne short 07caah                          ; 75 07
     cmp word [bp+006h], 08000h                ; 81 7e 06 00 80
-    jbe short 07c9bh                          ; 76 1d
+    jbe short 07cc7h                          ; 76 1d
     mov dx, ax                                ; 89 c2
     mov cx, 08000h                            ; b9 00 80
     les di, [bp+00ch]                         ; c4 7e 0c
@@ -11483,17 +11506,17 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     mov ax, es                                ; 8c c0
     add ax, 00800h                            ; 05 00 08
     mov word [bp+00eh], ax                    ; 89 46 0e
-    jmp short 07c6eh                          ; eb d3
+    jmp short 07c9ah                          ; eb d3
     mov dx, ax                                ; 89 c2
     mov cx, word [bp+006h]                    ; 8b 4e 06
     les di, [bp+00ch]                         ; c4 7e 0c
     rep insb                                  ; f3 6c
     mov es, [bp-00eh]                         ; 8e 46 f2
     cmp word [es:si+01ch], strict byte 00000h ; 26 83 7c 1c 00
-    je short 07cb6h                           ; 74 07
+    je short 07ce2h                           ; 74 07
     mov cx, word [es:si+01ch]                 ; 26 8b 4c 1c
     in AL, DX                                 ; ec
-    loop 07cb3h                               ; e2 fd
+    loop 07cdfh                               ; e2 fd
     xor dx, dx                                ; 31 d2
     mov ax, dx                                ; 89 d0
     lea sp, [bp-004h]                         ; 8d 66 fc
@@ -11501,7 +11524,7 @@ scsi_cmd_packet_:                            ; 0xf7b5d LB 0x166
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 0000ch                               ; c2 0c 00
-scsi_enumerate_attached_devices_:            ; 0xf7cc3 LB 0x3e5
+scsi_enumerate_attached_devices_:            ; 0xf7cef LB 0x3e4
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -11509,174 +11532,170 @@ scsi_enumerate_attached_devices_:            ; 0xf7cc3 LB 0x3e5
     push dx                                   ; 52
     push si                                   ; 56
     push di                                   ; 57
-    sub sp, 0021ch                            ; 81 ec 1c 02
+    sub sp, 0021eh                            ; 81 ec 1e 02
     push ax                                   ; 50
     mov dx, strict word 0000eh                ; ba 0e 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0166ch                               ; e8 93 99
+    call 0166ch                               ; e8 67 99
     mov si, 00122h                            ; be 22 01
-    mov word [bp-01ah], ax                    ; 89 46 e6
-    mov word [bp-010h], strict word 00000h    ; c7 46 f0 00 00
-    jmp near 08036h                           ; e9 4f 03
-    mov es, [bp-01ah]                         ; 8e 46 e6
-    cmp byte [es:si+001e8h], 004h             ; 26 80 bc e8 01 04
-    jnc near 0809eh                           ; 0f 83 aa 03
+    mov word [bp-018h], ax                    ; 89 46 e8
+    mov word [bp-00eh], strict word 00000h    ; c7 46 f2 00 00
+    jmp near 08055h                           ; e9 42 03
+    cmp AL, strict byte 004h                  ; 3c 04
+    jnc near 080c9h                           ; 0f 83 b0 03
     mov cx, strict word 0000ah                ; b9 0a 00
     xor bx, bx                                ; 31 db
     mov dx, ss                                ; 8c d2
-    lea ax, [bp-026h]                         ; 8d 46 da
-    call 0975ah                               ; e8 59 1a
-    mov byte [bp-026h], 025h                  ; c6 46 da 25
+    lea ax, [bp-028h]                         ; 8d 46 d8
+    call 097aah                               ; e8 84 1a
+    mov byte [bp-028h], 025h                  ; c6 46 d8 25
     push dword 000000008h                     ; 66 6a 08
-    lea dx, [bp-00226h]                       ; 8d 96 da fd
+    lea dx, [bp-00228h]                       ; 8d 96 d8 fd
     push SS                                   ; 16
     push dx                                   ; 52
     push strict byte 0000ah                   ; 6a 0a
-    movzx dx, byte [bp-010h]                  ; 0f b6 56 f0
+    movzx dx, byte [bp-00eh]                  ; 0f b6 56 f2
     mov cx, ss                                ; 8c d1
-    lea bx, [bp-026h]                         ; 8d 5e da
-    mov ax, word [bp-00228h]                  ; 8b 86 d8 fd
-    call 07885h                               ; e8 65 fb
+    lea bx, [bp-028h]                         ; 8d 5e d8
+    mov ax, word [bp-0022ah]                  ; 8b 86 d6 fd
+    call 07885h                               ; e8 40 fb
     test al, al                               ; 84 c0
-    je short 07d32h                           ; 74 0e
+    je short 07d57h                           ; 74 0e
     push 00b9ah                               ; 68 9a 0b
     push 00bd3h                               ; 68 d3 0b
     push strict byte 00007h                   ; 6a 07
-    call 01972h                               ; e8 43 9c
+    call 01972h                               ; e8 1e 9c
     add sp, strict byte 00006h                ; 83 c4 06
-    movzx ax, byte [bp-00225h]                ; 0f b6 86 db fd
-    movzx di, byte [bp-00226h]                ; 0f b6 be da fd
+    movzx ax, byte [bp-00227h]                ; 0f b6 86 d9 fd
+    movzx di, byte [bp-00228h]                ; 0f b6 be d8 fd
     sal di, 008h                              ; c1 e7 08
     xor bx, bx                                ; 31 db
     or di, ax                                 ; 09 c7
-    movzx ax, byte [bp-00224h]                ; 0f b6 86 dc fd
+    movzx ax, byte [bp-00226h]                ; 0f b6 86 da fd
     xor dx, dx                                ; 31 d2
     mov cx, strict word 00008h                ; b9 08 00
     sal ax, 1                                 ; d1 e0
     rcl dx, 1                                 ; d1 d2
-    loop 07d4dh                               ; e2 fa
+    loop 07d72h                               ; e2 fa
     or bx, ax                                 ; 09 c3
-    or dx, di                                 ; 09 fa
-    movzx ax, byte [bp-00223h]                ; 0f b6 86 dd fd
+    or di, dx                                 ; 09 d7
+    movzx ax, byte [bp-00225h]                ; 0f b6 86 db fd
     or bx, ax                                 ; 09 c3
-    mov word [bp-00eh], bx                    ; 89 5e f2
-    mov word [bp-018h], dx                    ; 89 56 e8
-    movzx di, byte [bp-00222h]                ; 0f b6 be de fd
-    sal di, 008h                              ; c1 e7 08
-    movzx dx, byte [bp-00221h]                ; 0f b6 96 df fd
+    mov word [bp-014h], bx                    ; 89 5e ec
+    add word [bp-014h], strict byte 00001h    ; 83 46 ec 01
+    adc di, strict byte 00000h                ; 83 d7 00
+    movzx ax, byte [bp-00224h]                ; 0f b6 86 dc fd
+    sal ax, 008h                              ; c1 e0 08
+    movzx dx, byte [bp-00223h]                ; 0f b6 96 dd fd
     xor bx, bx                                ; 31 db
-    or di, dx                                 ; 09 d7
-    movzx ax, byte [bp-00220h]                ; 0f b6 86 e0 fd
+    or ax, dx                                 ; 09 d0
+    mov word [bp-012h], ax                    ; 89 46 ee
+    movzx ax, byte [bp-00222h]                ; 0f b6 86 de fd
     xor dx, dx                                ; 31 d2
     mov cx, strict word 00008h                ; b9 08 00
     sal ax, 1                                 ; d1 e0
     rcl dx, 1                                 ; d1 d2
-    loop 07d7fh                               ; e2 fa
+    loop 07dabh                               ; e2 fa
     or ax, bx                                 ; 09 d8
-    or dx, di                                 ; 09 fa
-    movzx bx, byte [bp-0021fh]                ; 0f b6 9e e1 fd
+    or dx, word [bp-012h]                     ; 0b 56 ee
+    movzx bx, byte [bp-00221h]                ; 0f b6 9e df fd
     or ax, bx                                 ; 09 d8
-    mov word [bp-016h], ax                    ; 89 46 ea
+    mov word [bp-010h], ax                    ; 89 46 f0
     test dx, dx                               ; 85 d2
-    jne short 07d9ch                          ; 75 05
+    jne short 07dc9h                          ; 75 05
     cmp ax, 00200h                            ; 3d 00 02
-    je short 07dbch                           ; 74 20
+    je short 07de9h                           ; 74 20
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 8a 9b
+    call 01931h                               ; e8 5d 9b
     push dx                                   ; 52
-    push word [bp-016h]                       ; ff 76 ea
     push word [bp-010h]                       ; ff 76 f0
+    push word [bp-00eh]                       ; ff 76 f2
     push 00bf2h                               ; 68 f2 0b
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 bc 9b
+    call 01972h                               ; e8 8f 9b
     add sp, strict byte 0000ah                ; 83 c4 0a
-    jmp near 0802dh                           ; e9 71 02
-    mov es, [bp-01ah]                         ; 8e 46 e6
-    mov al, byte [es:si+001e8h]               ; 26 8a 84 e8 01
-    mov byte [bp-00ch], al                    ; 88 46 f4
+    jmp near 0804ch                           ; e9 63 02
+    mov al, byte [bp-00ch]                    ; 8a 46 f4
     cmp AL, strict byte 001h                  ; 3c 01
-    jc short 07dd7h                           ; 72 0c
-    jbe short 07ddfh                          ; 76 12
+    jc short 07dfch                           ; 72 0c
+    jbe short 07e04h                          ; 76 12
     cmp AL, strict byte 003h                  ; 3c 03
-    je short 07de7h                           ; 74 16
+    je short 07e0ch                           ; 74 16
     cmp AL, strict byte 002h                  ; 3c 02
-    je short 07de3h                           ; 74 0e
-    jmp short 07e33h                          ; eb 5c
+    je short 07e08h                           ; 74 0e
+    jmp short 07e5bh                          ; eb 5f
     test al, al                               ; 84 c0
-    jne short 07e33h                          ; 75 58
+    jne short 07e5bh                          ; 75 5b
     mov BL, strict byte 090h                  ; b3 90
-    jmp short 07de9h                          ; eb 0a
+    jmp short 07e0eh                          ; eb 0a
     mov BL, strict byte 098h                  ; b3 98
-    jmp short 07de9h                          ; eb 06
+    jmp short 07e0eh                          ; eb 06
     mov BL, strict byte 0a0h                  ; b3 a0
-    jmp short 07de9h                          ; eb 02
+    jmp short 07e0eh                          ; eb 02
     mov BL, strict byte 0a8h                  ; b3 a8
     mov al, bl                                ; 88 d8
     add AL, strict byte 007h                  ; 04 07
     movzx cx, al                              ; 0f b6 c8
     mov ax, cx                                ; 89 c8
-    call 016ach                               ; e8 b7 98
+    call 016ach                               ; e8 92 98
     test al, al                               ; 84 c0
-    je short 07e33h                           ; 74 3a
+    je short 07e5bh                           ; 74 3d
     mov al, bl                                ; 88 d8
     db  0feh, 0c0h
     ; inc al                                    ; fe c0
     xor ah, ah                                ; 30 e4
-    call 016ach                               ; e8 aa 98
+    call 016ach                               ; e8 85 98
     xor ah, ah                                ; 30 e4
-    mov dx, ax                                ; 89 c2
-    sal dx, 008h                              ; c1 e2 08
+    sal ax, 008h                              ; c1 e0 08
+    mov word [bp-012h], ax                    ; 89 46 ee
     movzx ax, bl                              ; 0f b6 c3
-    call 016ach                               ; e8 9d 98
+    call 016ach                               ; e8 77 98
     xor ah, ah                                ; 30 e4
-    add ax, dx                                ; 01 d0
+    add ax, word [bp-012h]                    ; 03 46 ee
     cwd                                       ; 99
-    mov di, ax                                ; 89 c7
-    mov word [bp-012h], dx                    ; 89 56 ee
+    mov word [bp-01eh], ax                    ; 89 46 e2
+    mov word [bp-016h], dx                    ; 89 56 ea
     mov al, bl                                ; 88 d8
     add AL, strict byte 002h                  ; 04 02
     xor ah, ah                                ; 30 e4
-    call 016ach                               ; e8 8a 98
+    call 016ach                               ; e8 62 98
     xor ah, ah                                ; 30 e4
-    mov word [bp-014h], ax                    ; 89 46 ec
+    mov word [bp-01ch], ax                    ; 89 46 e4
     mov ax, cx                                ; 89 c8
-    call 016ach                               ; e8 80 98
+    call 016ach                               ; e8 58 98
     xor ah, ah                                ; 30 e4
-    mov word [bp-01ch], ax                    ; 89 46 e4
-    jmp short 07e78h                          ; eb 45
-    mov ax, word [bp-018h]                    ; 8b 46 e8
-    cmp ax, strict word 00040h                ; 3d 40 00
-    jnbe short 07e3dh                         ; 77 02
-    jne short 07e49h                          ; 75 0c
-    mov word [bp-014h], 000ffh                ; c7 46 ec ff 00
-    mov word [bp-01ch], strict word 0003fh    ; c7 46 e4 3f 00
-    jmp short 07e61h                          ; eb 18
-    cmp ax, strict word 00020h                ; 3d 20 00
-    jnbe short 07e50h                         ; 77 02
-    jne short 07e57h                          ; 75 07
-    mov word [bp-014h], 00080h                ; c7 46 ec 80 00
-    jmp short 07e5ch                          ; eb 05
-    mov word [bp-014h], strict word 00040h    ; c7 46 ec 40 00
-    mov word [bp-01ch], strict word 00020h    ; c7 46 e4 20 00
-    mov bx, word [bp-014h]                    ; 8b 5e ec
-    imul bx, word [bp-01ch]                   ; 0f af 5e e4
-    mov ax, word [bp-00eh]                    ; 8b 46 f2
-    mov dx, word [bp-018h]                    ; 8b 56 e8
+    mov word [bp-01ah], ax                    ; 89 46 e6
+    jmp short 07e9ch                          ; eb 41
+    cmp di, strict byte 00040h                ; 83 ff 40
+    jnbe short 07e62h                         ; 77 02
+    jne short 07e6ch                          ; 75 0a
+    mov dword [bp-01ch], strict dword 0003f00ffh ; 66 c7 46 e4 ff 00 3f 00
+    jmp short 07e85h                          ; eb 19
+    cmp di, strict byte 00020h                ; 83 ff 20
+    jnbe short 07e73h                         ; 77 02
+    jne short 07e7dh                          ; 75 0a
+    mov dword [bp-01ch], strict dword 000200080h ; 66 c7 46 e4 80 00 20 00
+    jmp short 07e85h                          ; eb 08
+    mov dword [bp-01ch], strict dword 000200040h ; 66 c7 46 e4 40 00 20 00
+    mov bx, word [bp-01ch]                    ; 8b 5e e4
+    imul bx, word [bp-01ah]                   ; 0f af 5e e6
+    mov ax, word [bp-014h]                    ; 8b 46 ec
+    mov dx, di                                ; 89 fa
     xor cx, cx                                ; 31 c9
-    call 096f0h                               ; e8 7d 18
-    mov di, ax                                ; 89 c7
-    mov word [bp-012h], dx                    ; 89 56 ee
+    call 09740h                               ; e8 aa 18
+    mov word [bp-01eh], ax                    ; 89 46 e2
+    mov word [bp-016h], dx                    ; 89 56 ea
     mov dl, byte [bp-00ch]                    ; 8a 56 f4
     add dl, 008h                              ; 80 c2 08
     movzx bx, byte [bp-00ch]                  ; 0f b6 5e f4
     sal bx, 002h                              ; c1 e3 02
-    mov es, [bp-01ah]                         ; 8e 46 e6
+    mov es, [bp-018h]                         ; 8e 46 e8
     add bx, si                                ; 01 f3
-    mov ax, word [bp-00228h]                  ; 8b 86 d8 fd
+    mov ax, word [bp-0022ah]                  ; 8b 86 d6 fd
     mov word [es:bx+001d8h], ax               ; 26 89 87 d8 01
-    mov al, byte [bp-010h]                    ; 8a 46 f0
+    mov al, byte [bp-00eh]                    ; 8a 46 f2
     mov byte [es:bx+001dah], al               ; 26 88 87 da 01
     movzx ax, dl                              ; 0f b6 c2
     imul ax, ax, strict byte 00018h           ; 6b c0 18
@@ -11684,61 +11703,61 @@ scsi_enumerate_attached_devices_:            ; 0xf7cc3 LB 0x3e5
     add bx, ax                                ; 01 c3
     db  066h, 026h, 0c7h, 047h, 01eh, 004h, 0ffh, 000h, 000h
     ; mov dword [es:bx+01eh], strict dword 00000ff04h ; 66 26 c7 47 1e 04 ff 00 00
-    mov ax, word [bp-016h]                    ; 8b 46 ea
+    mov ax, word [bp-010h]                    ; 8b 46 f0
     mov word [es:bx+024h], ax                 ; 26 89 47 24
     mov byte [es:bx+023h], 001h               ; 26 c6 47 23 01
-    mov ax, word [bp-014h]                    ; 8b 46 ec
-    mov word [es:bx+026h], ax                 ; 26 89 47 26
     mov ax, word [bp-01ch]                    ; 8b 46 e4
+    mov word [es:bx+026h], ax                 ; 26 89 47 26
+    mov ax, word [bp-01ah]                    ; 8b 46 e6
     mov word [es:bx+02ah], ax                 ; 26 89 47 2a
-    cmp word [bp-012h], strict byte 00000h    ; 83 7e ee 00
-    jne short 07ed4h                          ; 75 06
-    cmp di, 00400h                            ; 81 ff 00 04
-    jbe short 07edch                          ; 76 08
+    cmp word [bp-016h], strict byte 00000h    ; 83 7e ea 00
+    jne short 07ef9h                          ; 75 07
+    cmp word [bp-01eh], 00400h                ; 81 7e e2 00 04
+    jbe short 07f01h                          ; 76 08
     mov word [es:bx+028h], 00400h             ; 26 c7 47 28 00 04
-    jmp short 07ee0h                          ; eb 04
-    mov word [es:bx+028h], di                 ; 26 89 7f 28
+    jmp short 07f08h                          ; eb 07
+    mov ax, word [bp-01eh]                    ; 8b 46 e2
+    mov word [es:bx+028h], ax                 ; 26 89 47 28
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 46 9a
-    push word [bp-018h]                       ; ff 76 e8
-    push word [bp-00eh]                       ; ff 76 f2
-    push word [bp-01ch]                       ; ff 76 e4
-    push word [bp-014h]                       ; ff 76 ec
+    call 01931h                               ; e8 1e 9a
     push di                                   ; 57
-    push word [bp-010h]                       ; ff 76 f0
+    push word [bp-014h]                       ; ff 76 ec
+    push dword [bp-01ch]                      ; 66 ff 76 e4
+    push word [bp-01eh]                       ; ff 76 e2
+    push word [bp-00eh]                       ; ff 76 f2
     movzx ax, byte [bp-00ch]                  ; 0f b6 46 f4
     push ax                                   ; 50
     push 00c20h                               ; 68 20 0c
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 6a 9a
+    call 01972h                               ; e8 44 9a
     add sp, strict byte 00012h                ; 83 c4 12
     movzx ax, dl                              ; 0f b6 c2
     imul ax, ax, strict byte 00018h           ; 6b c0 18
-    mov es, [bp-01ah]                         ; 8e 46 e6
+    mov es, [bp-018h]                         ; 8e 46 e8
     mov bx, si                                ; 89 f3
     add bx, ax                                ; 01 c3
-    mov ax, word [bp-014h]                    ; 8b 46 ec
-    mov word [es:bx+02ch], ax                 ; 26 89 47 2c
     mov ax, word [bp-01ch]                    ; 8b 46 e4
+    mov word [es:bx+02ch], ax                 ; 26 89 47 2c
+    mov ax, word [bp-01ah]                    ; 8b 46 e6
     mov word [es:bx+030h], ax                 ; 26 89 47 30
-    cmp word [bp-012h], strict byte 00000h    ; 83 7e ee 00
-    jne short 07f32h                          ; 75 06
-    cmp di, 00400h                            ; 81 ff 00 04
-    jbe short 07f3ah                          ; 76 08
+    cmp word [bp-016h], strict byte 00000h    ; 83 7e ea 00
+    jne short 07f59h                          ; 75 07
+    cmp word [bp-01eh], 00400h                ; 81 7e e2 00 04
+    jbe short 07f61h                          ; 76 08
     mov word [es:bx+02eh], 00400h             ; 26 c7 47 2e 00 04
-    jmp short 07f3eh                          ; eb 04
-    mov word [es:bx+02eh], di                 ; 26 89 7f 2e
+    jmp short 07f68h                          ; eb 07
+    mov ax, word [bp-01eh]                    ; 8b 46 e2
+    mov word [es:bx+02eh], ax                 ; 26 89 47 2e
     movzx ax, dl                              ; 0f b6 c2
     imul ax, ax, strict byte 00018h           ; 6b c0 18
-    mov es, [bp-01ah]                         ; 8e 46 e6
+    mov es, [bp-018h]                         ; 8e 46 e8
     mov bx, si                                ; 89 f3
     add bx, ax                                ; 01 c3
-    mov ax, word [bp-00eh]                    ; 8b 46 f2
+    mov ax, word [bp-014h]                    ; 8b 46 ec
     mov word [es:bx+032h], ax                 ; 26 89 47 32
-    mov ax, word [bp-018h]                    ; 8b 46 e8
-    mov word [es:bx+034h], ax                 ; 26 89 47 34
+    mov word [es:bx+034h], di                 ; 26 89 7f 34
     mov al, byte [es:si+0019eh]               ; 26 8a 84 9e 01
     mov ah, byte [bp-00ch]                    ; 8a 66 f4
     add ah, 008h                              ; 80 c4 08
@@ -11750,44 +11769,41 @@ scsi_enumerate_attached_devices_:            ; 0xf7cc3 LB 0x3e5
     mov byte [es:si+0019eh], al               ; 26 88 84 9e 01
     mov dx, strict word 00075h                ; ba 75 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 01650h                               ; e8 d2 96
+    call 01650h                               ; e8 ab 96
     db  0feh, 0c0h
     ; inc al                                    ; fe c0
     movzx bx, al                              ; 0f b6 d8
     mov dx, strict word 00075h                ; ba 75 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0165eh                               ; e8 d2 96
+    call 0165eh                               ; e8 ab 96
     inc byte [bp-00ch]                        ; fe 46 f4
-    mov al, byte [bp-00ch]                    ; 8a 46 f4
-    mov es, [bp-01ah]                         ; 8e 46 e6
-    mov byte [es:si+001e8h], al               ; 26 88 84 e8 01
-    jmp near 0802dh                           ; e9 90 00
+    jmp near 08041h                           ; e9 88 00
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 89 99
-    push word [bp-010h]                       ; ff 76 f0
+    call 01931h                               ; e8 6d 99
+    push word [bp-00eh]                       ; ff 76 f2
     movzx ax, byte [bp-00ch]                  ; 0f b6 46 f4
     push ax                                   ; 50
     push 00c4ah                               ; 68 4a 0c
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 ba 99
+    call 01972h                               ; e8 9e 99
     add sp, strict byte 00008h                ; 83 c4 08
     mov dl, byte [bp-00ch]                    ; 8a 56 f4
     add dl, 008h                              ; 80 c2 08
-    test byte [bp-00225h], 080h               ; f6 86 db fd 80
+    test byte [bp-00227h], 080h               ; f6 86 d9 fd 80
     db  00fh, 095h, 0c0h
     ; setne al                                  ; 0f 95 c0
     xor ah, ah                                ; 30 e4
     mov cx, ax                                ; 89 c1
     movzx ax, byte [bp-00ch]                  ; 0f b6 46 f4
     sal ax, 002h                              ; c1 e0 02
-    mov es, [bp-01ah]                         ; 8e 46 e6
+    mov es, [bp-018h]                         ; 8e 46 e8
     mov bx, si                                ; 89 f3
     add bx, ax                                ; 01 c3
-    mov ax, word [bp-00228h]                  ; 8b 86 d8 fd
+    mov ax, word [bp-0022ah]                  ; 8b 86 d6 fd
     mov word [es:bx+001d8h], ax               ; 26 89 87 d8 01
-    mov al, byte [bp-010h]                    ; 8a 46 f0
+    mov al, byte [bp-00eh]                    ; 8a 46 f2
     mov byte [es:bx+001dah], al               ; 26 88 87 da 01
     movzx ax, dl                              ; 0f b6 c2
     imul ax, ax, strict byte 00018h           ; 6b c0 18
@@ -11807,45 +11823,49 @@ scsi_enumerate_attached_devices_:            ; 0xf7cc3 LB 0x3e5
     mov byte [es:si+001afh], al               ; 26 88 84 af 01
     inc byte [bp-00ch]                        ; fe 46 f4
     mov al, byte [bp-00ch]                    ; 8a 46 f4
+    mov es, [bp-018h]                         ; 8e 46 e8
     mov byte [es:si+001e8h], al               ; 26 88 84 e8 01
-    inc word [bp-010h]                        ; ff 46 f0
-    cmp word [bp-010h], strict byte 00010h    ; 83 7e f0 10
-    jnl short 0809eh                          ; 7d 68
-    mov byte [bp-026h], 012h                  ; c6 46 da 12
+    inc word [bp-00eh]                        ; ff 46 f2
+    cmp word [bp-00eh], strict byte 00010h    ; 83 7e f2 10
+    jnl short 080c9h                          ; 7d 74
+    mov byte [bp-028h], 012h                  ; c6 46 d8 12
     xor al, al                                ; 30 c0
+    mov byte [bp-027h], al                    ; 88 46 d9
+    mov byte [bp-026h], al                    ; 88 46 da
     mov byte [bp-025h], al                    ; 88 46 db
-    mov byte [bp-024h], al                    ; 88 46 dc
+    mov byte [bp-024h], 005h                  ; c6 46 dc 05
     mov byte [bp-023h], al                    ; 88 46 dd
-    mov byte [bp-022h], 005h                  ; c6 46 de 05
-    mov byte [bp-021h], al                    ; 88 46 df
     push dword 000000005h                     ; 66 6a 05
-    lea dx, [bp-00226h]                       ; 8d 96 da fd
+    lea dx, [bp-00228h]                       ; 8d 96 d8 fd
     push SS                                   ; 16
     push dx                                   ; 52
     push strict byte 00006h                   ; 6a 06
-    movzx dx, byte [bp-010h]                  ; 0f b6 56 f0
+    movzx dx, byte [bp-00eh]                  ; 0f b6 56 f2
     mov cx, ss                                ; 8c d1
-    lea bx, [bp-026h]                         ; 8d 5e da
-    mov ax, word [bp-00228h]                  ; 8b 86 d8 fd
-    call 07885h                               ; e8 1e f8
+    lea bx, [bp-028h]                         ; 8d 5e d8
+    mov ax, word [bp-0022ah]                  ; 8b 86 d6 fd
+    call 07885h                               ; e8 ff f7
     test al, al                               ; 84 c0
-    je short 08079h                           ; 74 0e
+    je short 08098h                           ; 74 0e
     push 00b9ah                               ; 68 9a 0b
     push 00bbah                               ; 68 ba 0b
     push strict byte 00007h                   ; 6a 07
-    call 01972h                               ; e8 fc 98
+    call 01972h                               ; e8 dd 98
     add sp, strict byte 00006h                ; 83 c4 06
-    test byte [bp-00226h], 0e0h               ; f6 86 da fd e0
-    jne short 08089h                          ; 75 09
-    test byte [bp-00226h], 01fh               ; f6 86 da fd 1f
-    je near 07ce7h                            ; 0f 84 5e fc
-    test byte [bp-00226h], 0e0h               ; f6 86 da fd e0
-    jne short 0802dh                          ; 75 9d
-    mov al, byte [bp-00226h]                  ; 8a 86 da fd
+    mov es, [bp-018h]                         ; 8e 46 e8
+    mov al, byte [es:si+001e8h]               ; 26 8a 84 e8 01
+    mov byte [bp-00ch], al                    ; 88 46 f4
+    test byte [bp-00228h], 0e0h               ; f6 86 d8 fd e0
+    jne short 080b3h                          ; 75 09
+    test byte [bp-00228h], 01fh               ; f6 86 d8 fd 1f
+    je near 07d13h                            ; 0f 84 60 fc
+    test byte [bp-00228h], 0e0h               ; f6 86 d8 fd e0
+    jne short 08041h                          ; 75 87
+    mov al, byte [bp-00228h]                  ; 8a 86 d8 fd
     and AL, strict byte 01fh                  ; 24 1f
     cmp AL, strict byte 005h                  ; 3c 05
-    je near 07f9dh                            ; 0f 84 01 ff
-    jmp short 0802dh                          ; eb 8f
+    je near 07fb9h                            ; 0f 84 f3 fe
+    jmp near 08041h                           ; e9 78 ff
     lea sp, [bp-00ah]                         ; 8d 66 f6
     pop di                                    ; 5f
     pop si                                    ; 5e
@@ -11854,12 +11874,12 @@ scsi_enumerate_attached_devices_:            ; 0xf7cc3 LB 0x3e5
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-_scsi_init:                                  ; 0xf80a8 LB 0x66
+_scsi_init:                                  ; 0xf80d3 LB 0x66
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     mov dx, strict word 0000eh                ; ba 0e 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0166ch                               ; e8 b8 95
+    call 0166ch                               ; e8 8d 95
     mov bx, 00122h                            ; bb 22 01
     mov es, ax                                ; 8e c0
     mov byte [es:bx+001e8h], 000h             ; 26 c6 87 e8 01 00
@@ -11870,12 +11890,12 @@ _scsi_init:                                  ; 0xf80a8 LB 0x66
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     cmp AL, strict byte 055h                  ; 3c 55
-    jne short 080d8h                          ; 75 0c
+    jne short 08103h                          ; 75 0c
     xor al, al                                ; 30 c0
     mov dx, 00433h                            ; ba 33 04
     out DX, AL                                ; ee
     mov ax, 00430h                            ; b8 30 04
-    call 07cc3h                               ; e8 eb fb
+    call 07cefh                               ; e8 ec fb
     mov AL, strict byte 055h                  ; b0 55
     mov dx, 00436h                            ; ba 36 04
     out DX, AL                                ; ee
@@ -11883,12 +11903,12 @@ _scsi_init:                                  ; 0xf80a8 LB 0x66
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     cmp AL, strict byte 055h                  ; 3c 55
-    jne short 080f1h                          ; 75 0c
+    jne short 0811ch                          ; 75 0c
     xor al, al                                ; 30 c0
     mov dx, 00437h                            ; ba 37 04
     out DX, AL                                ; ee
     mov ax, 00434h                            ; b8 34 04
-    call 07cc3h                               ; e8 d2 fb
+    call 07cefh                               ; e8 d3 fb
     mov AL, strict byte 055h                  ; b0 55
     mov dx, 0043ah                            ; ba 3a 04
     out DX, AL                                ; ee
@@ -11896,16 +11916,16 @@ _scsi_init:                                  ; 0xf80a8 LB 0x66
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     cmp AL, strict byte 055h                  ; 3c 55
-    jne short 0810ah                          ; 75 0c
+    jne short 08135h                          ; 75 0c
     xor al, al                                ; 30 c0
     mov dx, 0043bh                            ; ba 3b 04
     out DX, AL                                ; ee
     mov ax, 00438h                            ; b8 38 04
-    call 07cc3h                               ; e8 b9 fb
+    call 07cefh                               ; e8 ba fb
     mov sp, bp                                ; 89 ec
     pop bp                                    ; 5d
     retn                                      ; c3
-high_bits_save_:                             ; 0xf810e LB 0x17
+high_bits_save_:                             ; 0xf8139 LB 0x17
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -11917,7 +11937,7 @@ high_bits_save_:                             ; 0xf810e LB 0x17
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-high_bits_restore_:                          ; 0xf8125 LB 0x17
+high_bits_restore_:                          ; 0xf8150 LB 0x17
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -11929,7 +11949,7 @@ high_bits_restore_:                          ; 0xf8125 LB 0x17
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_ctrl_set_bits_:                         ; 0xf813c LB 0x43
+ahci_ctrl_set_bits_:                         ; 0xf8167 LB 0x43
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -11967,7 +11987,7 @@ ahci_ctrl_set_bits_:                         ; 0xf813c LB 0x43
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_ctrl_clear_bits_:                       ; 0xf817f LB 0x47
+ahci_ctrl_clear_bits_:                       ; 0xf81aa LB 0x47
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -12007,7 +12027,7 @@ ahci_ctrl_clear_bits_:                       ; 0xf817f LB 0x47
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_ctrl_is_bit_set_:                       ; 0xf81c6 LB 0x39
+ahci_ctrl_is_bit_set_:                       ; 0xf81f1 LB 0x39
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -12029,18 +12049,18 @@ ahci_ctrl_is_bit_set_:                       ; 0xf81c6 LB 0x39
     shr eax, 010h                             ; 66 c1 e8 10
     xchg dx, ax                               ; 92
     test dx, di                               ; 85 fa
-    jne short 081f2h                          ; 75 04
+    jne short 0821dh                          ; 75 04
     test ax, bx                               ; 85 d8
-    je short 081f6h                           ; 74 04
+    je short 08221h                           ; 74 04
     mov AL, strict byte 001h                  ; b0 01
-    jmp short 081f8h                          ; eb 02
+    jmp short 08223h                          ; eb 02
     xor al, al                                ; 30 c0
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_ctrl_extract_bits_:                     ; 0xf81ff LB 0x1b
+ahci_ctrl_extract_bits_:                     ; 0xf822a LB 0x1b
     push si                                   ; 56
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
@@ -12048,14 +12068,14 @@ ahci_ctrl_extract_bits_:                     ; 0xf81ff LB 0x1b
     and ax, bx                                ; 21 d8
     and dx, cx                                ; 21 ca
     movzx cx, byte [bp+006h]                  ; 0f b6 4e 06
-    jcxz 08215h                               ; e3 06
+    jcxz 08240h                               ; e3 06
     shr dx, 1                                 ; d1 ea
     rcr ax, 1                                 ; d1 d8
-    loop 0820fh                               ; e2 fa
+    loop 0823ah                               ; e2 fa
     pop bp                                    ; 5d
     pop si                                    ; 5e
     retn 00002h                               ; c2 02 00
-ahci_addr_to_phys_:                          ; 0xf821a LB 0x1e
+ahci_addr_to_phys_:                          ; 0xf8245 LB 0x1e
     push bx                                   ; 53
     push cx                                   ; 51
     push bp                                   ; 55
@@ -12066,7 +12086,7 @@ ahci_addr_to_phys_:                          ; 0xf821a LB 0x1e
     mov cx, strict word 00004h                ; b9 04 00
     sal ax, 1                                 ; d1 e0
     rcl dx, 1                                 ; d1 d2
-    loop 08228h                               ; e2 fa
+    loop 08253h                               ; e2 fa
     xor cx, cx                                ; 31 c9
     add ax, bx                                ; 01 d8
     adc dx, cx                                ; 11 ca
@@ -12074,7 +12094,7 @@ ahci_addr_to_phys_:                          ; 0xf821a LB 0x1e
     pop cx                                    ; 59
     pop bx                                    ; 5b
     retn                                      ; c3
-ahci_port_cmd_sync_:                         ; 0xf8238 LB 0xd5
+ahci_port_cmd_sync_:                         ; 0xf8263 LB 0xd5
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -12088,7 +12108,7 @@ ahci_port_cmd_sync_:                         ; 0xf8238 LB 0xd5
     mov byte [bp-008h], al                    ; 88 46 f8
     mov di, word [es:si+00260h]               ; 26 8b bc 60 02
     cmp AL, strict byte 0ffh                  ; 3c ff
-    je near 08305h                            ; 0f 84 aa 00
+    je near 08330h                            ; 0f 84 aa 00
     movzx cx, byte [es:si+00263h]             ; 26 0f b6 8c 63 02
     xor dx, dx                                ; 31 d2
     or dl, 080h                               ; 80 ca 80
@@ -12100,7 +12120,7 @@ ahci_port_cmd_sync_:                         ; 0xf8238 LB 0xd5
     ; mov dword [es:si+004h], strict dword 000000000h ; 66 26 c7 44 04 00 00 00 00
     lea ax, [si+00080h]                       ; 8d 84 80 00
     mov dx, es                                ; 8c c2
-    call 0821ah                               ; e8 96 ff
+    call 08245h                               ; e8 96 ff
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov word [es:si+008h], ax                 ; 26 89 44 08
     mov word [es:si+00ah], dx                 ; 26 89 54 0a
@@ -12110,7 +12130,7 @@ ahci_port_cmd_sync_:                         ; 0xf8238 LB 0xd5
     mov bx, strict word 00011h                ; bb 11 00
     xor cx, cx                                ; 31 c9
     mov ax, di                                ; 89 f8
-    call 0813ch                               ; e8 98 fe
+    call 08167h                               ; e8 98 fe
     lea ax, [si+00138h]                       ; 8d 84 38 01
     cwd                                       ; 99
     mov cx, dx                                ; 89 d1
@@ -12137,27 +12157,27 @@ ahci_port_cmd_sync_:                         ; 0xf8238 LB 0xd5
     mov cx, 04000h                            ; b9 00 40
     mov dx, si                                ; 89 f2
     mov ax, di                                ; 89 f8
-    call 081c6h                               ; e8 e2 fe
+    call 081f1h                               ; e8 e2 fe
     test al, al                               ; 84 c0
-    je short 082c7h                           ; 74 df
+    je short 082f2h                           ; 74 df
     mov bx, strict word 00001h                ; bb 01 00
     xor cx, cx                                ; 31 c9
     mov dx, si                                ; 89 f2
     mov ax, di                                ; 89 f8
-    call 0813ch                               ; e8 48 fe
+    call 08167h                               ; e8 48 fe
     mov dx, word [bp-00ch]                    ; 8b 56 f4
     add dx, 00118h                            ; 81 c2 18 01
     mov bx, strict word 00001h                ; bb 01 00
     xor cx, cx                                ; 31 c9
     mov ax, di                                ; 89 f8
-    call 0817fh                               ; e8 7a fe
+    call 081aah                               ; e8 7a fe
     lea sp, [bp-006h]                         ; 8d 66 fa
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_cmd_data_:                              ; 0xf830d LB 0x1ca
+ahci_cmd_data_:                              ; 0xf8338 LB 0x1e4
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -12165,72 +12185,72 @@ ahci_cmd_data_:                              ; 0xf830d LB 0x1ca
     push di                                   ; 57
     sub sp, strict byte 00010h                ; 83 ec 10
     mov di, ax                                ; 89 c7
-    mov word [bp-012h], dx                    ; 89 56 ee
+    mov word [bp-00ch], dx                    ; 89 56 f4
     mov byte [bp-008h], bl                    ; 88 5e f8
     xor si, si                                ; 31 f6
     mov es, dx                                ; 8e c2
     mov ax, word [es:di+001eeh]               ; 26 8b 85 ee 01
     mov word [bp-00ah], ax                    ; 89 46 f6
-    mov word [bp-00eh], si                    ; 89 76 f2
-    mov word [bp-00ch], ax                    ; 89 46 f4
+    mov word [bp-010h], si                    ; 89 76 f0
+    mov word [bp-00eh], ax                    ; 89 46 f2
     mov ax, word [es:di+00ah]                 ; 26 8b 45 0a
-    mov word [bp-010h], ax                    ; 89 46 f0
-    mov ax, word [es:di+00ch]                 ; 26 8b 45 0c
     mov word [bp-016h], ax                    ; 89 46 ea
+    mov ax, word [es:di+00ch]                 ; 26 8b 45 0c
+    mov word [bp-012h], ax                    ; 89 46 ee
     mov cx, strict word 00040h                ; b9 40 00
     xor bx, bx                                ; 31 db
     mov ax, 00080h                            ; b8 80 00
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 0975ah                               ; e8 0e 14
+    call 097aah                               ; e8 33 14
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov word [es:si+00080h], 08027h           ; 26 c7 84 80 00 27 80
     mov al, byte [bp-008h]                    ; 8a 46 f8
     mov byte [es:si+00082h], al               ; 26 88 84 82 00
     mov byte [es:si+00083h], 000h             ; 26 c6 84 83 00 00
-    mov es, [bp-012h]                         ; 8e 46 ee
+    mov es, [bp-00ch]                         ; 8e 46 f4
     mov al, byte [es:di]                      ; 26 8a 05
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov byte [es:si+00084h], al               ; 26 88 84 84 00
-    mov es, [bp-012h]                         ; 8e 46 ee
+    mov es, [bp-00ch]                         ; 8e 46 f4
     mov ax, word [es:di]                      ; 26 8b 05
     mov bx, word [es:di+002h]                 ; 26 8b 5d 02
     mov cx, strict word 00008h                ; b9 08 00
     shr bx, 1                                 ; d1 eb
     rcr ax, 1                                 ; d1 d8
-    loop 0837fh                               ; e2 fa
+    loop 083aah                               ; e2 fa
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov byte [es:si+00085h], al               ; 26 88 84 85 00
-    mov es, [bp-012h]                         ; 8e 46 ee
+    mov es, [bp-00ch]                         ; 8e 46 f4
     mov ax, word [es:di+002h]                 ; 26 8b 45 02
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov byte [es:si+00086h], al               ; 26 88 84 86 00
     mov byte [es:si+00087h], 040h             ; 26 c6 84 87 00 40
-    mov es, [bp-012h]                         ; 8e 46 ee
+    mov es, [bp-00ch]                         ; 8e 46 f4
     mov ax, word [es:di+002h]                 ; 26 8b 45 02
     shr ax, 008h                              ; c1 e8 08
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov byte [es:si+00088h], al               ; 26 88 84 88 00
     mov word [es:si+00089h], strict word 00000h ; 26 c7 84 89 00 00 00
     mov byte [es:si+0008bh], 000h             ; 26 c6 84 8b 00 00
-    mov al, byte [bp-010h]                    ; 8a 46 f0
+    mov al, byte [bp-016h]                    ; 8a 46 ea
     mov byte [es:si+0008ch], al               ; 26 88 84 8c 00
-    mov ax, word [bp-010h]                    ; 8b 46 f0
+    mov ax, word [bp-016h]                    ; 8b 46 ea
     shr ax, 008h                              ; c1 e8 08
     mov byte [es:si+0008dh], al               ; 26 88 84 8d 00
     mov word [es:si+00276h], strict word 00010h ; 26 c7 84 76 02 10 00
-    mov ax, word [bp-010h]                    ; 8b 46 f0
+    mov ax, word [bp-016h]                    ; 8b 46 ea
     xor dx, dx                                ; 31 d2
-    mov bx, word [bp-016h]                    ; 8b 5e ea
+    mov bx, word [bp-012h]                    ; 8b 5e ee
     xor cx, cx                                ; 31 c9
-    call 09729h                               ; e8 41 13
+    call 09779h                               ; e8 66 13
     push dx                                   ; 52
     push ax                                   ; 50
-    mov es, [bp-012h]                         ; 8e 46 ee
+    mov es, [bp-00ch]                         ; 8e 46 f4
     mov bx, word [es:di+004h]                 ; 26 8b 5d 04
     mov cx, word [es:di+006h]                 ; 26 8b 4d 06
     mov ax, 0026ah                            ; b8 6a 02
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 09642h                               ; e8 44 12
+    call 09688h                               ; e8 5f 12
     mov es, [bp-00ah]                         ; 8e 46 f6
     movzx ax, byte [es:si+00263h]             ; 26 0f b6 84 63 02
     mov dx, word [es:si+0027eh]               ; 26 8b 94 7e 02
@@ -12243,62 +12263,72 @@ ahci_cmd_data_:                              ; 0xf830d LB 0x1ca
     mov word [es:bx+0010ch], dx               ; 26 89 97 0c 01
     mov dx, word [bp-014h]                    ; 8b 56 ec
     mov word [es:bx+0010eh], dx               ; 26 89 97 0e 01
-    mov cx, word [es:si+0027ah]               ; 26 8b 8c 7a 02
-    mov dx, word [es:si+0027ch]               ; 26 8b 94 7c 02
-    mov word [es:bx+00100h], cx               ; 26 89 8f 00 01
-    mov word [es:bx+00102h], dx               ; 26 89 97 02 01
+    mov dx, word [es:si+0027ah]               ; 26 8b 94 7a 02
+    mov cx, word [es:si+0027ch]               ; 26 8b 8c 7c 02
+    mov word [es:bx+00100h], dx               ; 26 89 97 00 01
+    mov word [es:bx+00102h], cx               ; 26 89 8f 02 01
     inc ax                                    ; 40
-    mov es, [bp-012h]                         ; 8e 46 ee
+    mov es, [bp-00ch]                         ; 8e 46 f4
     cmp word [es:di+01ch], strict byte 00000h ; 26 83 7d 1c 00
-    je short 08477h                           ; 74 2c
+    je short 084a2h                           ; 74 2c
     mov dx, word [es:di+01ch]                 ; 26 8b 55 1c
     dec dx                                    ; 4a
-    mov di, ax                                ; 89 c7
-    sal di, 004h                              ; c1 e7 04
+    mov bx, ax                                ; 89 c3
+    sal bx, 004h                              ; c1 e3 04
     mov es, [bp-00ah]                         ; 8e 46 f6
-    mov word [es:di+0010ch], dx               ; 26 89 95 0c 01
-    mov word [es:di+0010eh], si               ; 26 89 b5 0e 01
+    mov word [es:bx+0010ch], dx               ; 26 89 97 0c 01
+    mov word [es:bx+0010eh], si               ; 26 89 b7 0e 01
     mov dx, word [es:si+00264h]               ; 26 8b 94 64 02
-    mov bx, word [es:si+00266h]               ; 26 8b 9c 66 02
-    mov word [es:di+00100h], dx               ; 26 89 95 00 01
-    mov word [es:di+00102h], bx               ; 26 89 9d 02 01
+    mov cx, word [es:si+00266h]               ; 26 8b 8c 66 02
+    mov word [es:bx+00100h], dx               ; 26 89 97 00 01
+    mov word [es:bx+00102h], cx               ; 26 89 8f 02 01
     inc ax                                    ; 40
-    les bx, [bp-00eh]                         ; c4 5e f2
+    les bx, [bp-010h]                         ; c4 5e f0
     mov byte [es:bx+00263h], al               ; 26 88 87 63 02
     xor ax, ax                                ; 31 c0
-    les bx, [bp-00eh]                         ; c4 5e f2
+    les bx, [bp-010h]                         ; c4 5e f0
     movzx dx, byte [es:bx+00263h]             ; 26 0f b6 97 63 02
     cmp ax, dx                                ; 39 d0
-    jnc short 08491h                          ; 73 03
+    jnc short 084bch                          ; 73 03
     inc ax                                    ; 40
-    jmp short 08481h                          ; eb f0
+    jmp short 084ach                          ; eb f0
     mov al, byte [bp-008h]                    ; 8a 46 f8
     cmp AL, strict byte 035h                  ; 3c 35
-    jne short 0849eh                          ; 75 06
+    jne short 084c9h                          ; 75 06
     mov byte [bp-008h], 040h                  ; c6 46 f8 40
-    jmp short 084b2h                          ; eb 14
+    jmp short 084ddh                          ; eb 14
     cmp AL, strict byte 0a0h                  ; 3c a0
-    jne short 084aeh                          ; 75 0c
+    jne short 084d9h                          ; 75 0c
     or byte [bp-008h], 020h                   ; 80 4e f8 20
     or byte [es:bx+00083h], 001h              ; 26 80 8f 83 00 01
-    jmp short 084b2h                          ; eb 04
+    jmp short 084ddh                          ; eb 04
     mov byte [bp-008h], 000h                  ; c6 46 f8 00
     or byte [bp-008h], 005h                   ; 80 4e f8 05
     movzx bx, byte [bp-008h]                  ; 0f b6 5e f8
-    mov ax, word [bp-00eh]                    ; 8b 46 f2
-    mov dx, word [bp-00ch]                    ; 8b 56 f4
-    call 08238h                               ; e8 75 fd
-    mov ax, word [bp-00eh]                    ; 8b 46 f2
+    mov ax, word [bp-010h]                    ; 8b 46 f0
+    mov dx, word [bp-00eh]                    ; 8b 56 f2
+    call 08263h                               ; e8 75 fd
+    mov cx, word [bp-00eh]                    ; 8b 4e f2
+    mov bx, word [bp-010h]                    ; 8b 5e f0
+    add bx, 00240h                            ; 81 c3 40 02
+    mov ax, word [bp-010h]                    ; 8b 46 f0
     add ax, 0026ah                            ; 05 6a 02
-    mov dx, word [bp-00ch]                    ; 8b 56 f4
-    call 096bbh                               ; e8 ec 11
+    mov dx, cx                                ; 89 ca
+    call 09701h                               ; e8 fe 11
+    mov es, cx                                ; 8e c1
+    mov al, byte [es:bx+003h]                 ; 26 8a 47 03
+    test al, al                               ; 84 c0
+    je short 08512h                           ; 74 05
+    mov ax, strict word 00004h                ; b8 04 00
+    jmp short 08514h                          ; eb 02
+    xor ah, ah                                ; 30 e4
     lea sp, [bp-006h]                         ; 8d 66 fa
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_port_deinit_current_:                   ; 0xf84d7 LB 0x144
+ahci_port_deinit_current_:                   ; 0xf851c LB 0x144
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -12313,14 +12343,14 @@ ahci_port_deinit_current_:                   ; 0xf84d7 LB 0x144
     mov al, byte [es:di+00262h]               ; 26 8a 85 62 02
     mov byte [bp-00ah], al                    ; 88 46 f6
     cmp AL, strict byte 0ffh                  ; 3c ff
-    je near 08612h                            ; 0f 84 17 01
+    je near 08657h                            ; 0f 84 17 01
     movzx dx, al                              ; 0f b6 d0
     sal dx, 007h                              ; c1 e2 07
     add dx, 00118h                            ; 81 c2 18 01
     mov bx, strict word 00011h                ; bb 11 00
     xor cx, cx                                ; 31 c9
     mov ax, si                                ; 89 f0
-    call 0817fh                               ; e8 70 fc
+    call 081aah                               ; e8 56 fc
     movzx ax, byte [bp-00ah]                  ; 0f b6 46 f6
     sal ax, 007h                              ; c1 e0 07
     mov word [bp-00eh], ax                    ; 89 46 f2
@@ -12329,24 +12359,24 @@ ahci_port_deinit_current_:                   ; 0xf84d7 LB 0x144
     mov bx, 0c011h                            ; bb 11 c0
     xor cx, cx                                ; 31 c9
     mov ax, si                                ; 89 f0
-    call 081c6h                               ; e8 9d fc
+    call 081f1h                               ; e8 83 fc
     cmp AL, strict byte 001h                  ; 3c 01
-    je short 0850fh                           ; 74 e2
+    je short 08554h                           ; 74 e2
     mov cx, strict word 00020h                ; b9 20 00
     xor bx, bx                                ; 31 db
     mov ax, di                                ; 89 f8
     mov dx, word [bp-00ch]                    ; 8b 56 f4
-    call 0975ah                               ; e8 20 12
+    call 097aah                               ; e8 2b 12
     lea ax, [di+00080h]                       ; 8d 85 80 00
     mov cx, strict word 00040h                ; b9 40 00
     xor bx, bx                                ; 31 db
     mov dx, word [bp-00ch]                    ; 8b 56 f4
-    call 0975ah                               ; e8 11 12
+    call 097aah                               ; e8 1c 12
     lea ax, [di+00200h]                       ; 8d 85 00 02
     mov cx, strict word 00060h                ; b9 60 00
     xor bx, bx                                ; 31 db
     mov dx, word [bp-00ch]                    ; 8b 56 f4
-    call 0975ah                               ; e8 02 12
+    call 097aah                               ; e8 0d 12
     mov ax, word [bp-00eh]                    ; 8b 46 f2
     add ax, 00108h                            ; 05 08 01
     cwd                                       ; 99
@@ -12448,7 +12478,7 @@ ahci_port_deinit_current_:                   ; 0xf84d7 LB 0x144
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_port_init_:                             ; 0xf861b LB 0x206
+ahci_port_init_:                             ; 0xf8660 LB 0x206
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -12458,7 +12488,7 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     mov si, ax                                ; 89 c6
     mov word [bp-00ah], dx                    ; 89 56 f6
     mov byte [bp-008h], bl                    ; 88 5e f8
-    call 084d7h                               ; e8 a8 fe
+    call 0851ch                               ; e8 a8 fe
     movzx dx, bl                              ; 0f b6 d3
     sal dx, 007h                              ; c1 e2 07
     add dx, 00118h                            ; 81 c2 18 01
@@ -12466,7 +12496,7 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     mov ax, word [es:si+00260h]               ; 26 8b 84 60 02
     mov bx, strict word 00011h                ; bb 11 00
     xor cx, cx                                ; 31 c9
-    call 0817fh                               ; e8 36 fb
+    call 081aah                               ; e8 1c fb
     movzx di, byte [bp-008h]                  ; 0f b6 7e f8
     sal di, 007h                              ; c1 e7 07
     lea dx, [di+00118h]                       ; 8d 95 18 01
@@ -12474,26 +12504,26 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     mov ax, word [es:si+00260h]               ; 26 8b 84 60 02
     mov bx, 0c011h                            ; bb 11 c0
     xor cx, cx                                ; 31 c9
-    call 081c6h                               ; e8 62 fb
+    call 081f1h                               ; e8 48 fb
     cmp AL, strict byte 001h                  ; 3c 01
-    je short 08649h                           ; 74 e1
+    je short 0868eh                           ; 74 e1
     mov cx, strict word 00020h                ; b9 20 00
     xor bx, bx                                ; 31 db
     mov ax, si                                ; 89 f0
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 0975ah                               ; e8 e5 10
+    call 097aah                               ; e8 f0 10
     lea ax, [si+00080h]                       ; 8d 84 80 00
     mov cx, strict word 00040h                ; b9 40 00
     xor bx, bx                                ; 31 db
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 0975ah                               ; e8 d6 10
+    call 097aah                               ; e8 e1 10
     mov ax, si                                ; 89 f0
     add ah, 002h                              ; 80 c4 02
     mov word [bp-00ch], ax                    ; 89 46 f4
     mov cx, strict word 00060h                ; b9 60 00
     xor bx, bx                                ; 31 db
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 0975ah                               ; e8 c3 10
+    call 097aah                               ; e8 ce 10
     lea ax, [di+00108h]                       ; 8d 85 08 01
     cwd                                       ; 99
     mov es, [bp-00ah]                         ; 8e 46 f6
@@ -12507,7 +12537,7 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     out DX, eax                               ; 66 ef
     mov ax, word [bp-00ch]                    ; 8b 46 f4
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 0821ah                               ; e8 60 fb
+    call 08245h                               ; e8 46 fb
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov bx, word [es:si+00260h]               ; 26 8b 9c 60 02
     add bx, strict byte 00004h                ; 83 c3 04
@@ -12552,7 +12582,7 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     out DX, eax                               ; 66 ef
     mov ax, si                                ; 89 f0
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 0821ah                               ; e8 f4 fa
+    call 08245h                               ; e8 da fa
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov bx, word [es:si+00260h]               ; 26 8b 9c 60 02
     add bx, strict byte 00004h                ; 83 c3 04
@@ -12657,46 +12687,46 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
- at ahci_read_sectors:                          ; 0xf8821 LB 0x94
+ at ahci_read_sectors:                          ; 0xf8866 LB 0x93
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
     push di                                   ; 57
-    les di, [bp+004h]                         ; c4 7e 04
-    movzx di, byte [es:di+008h]               ; 26 0f b6 7d 08
-    sub di, strict byte 0000ch                ; 83 ef 0c
-    cmp di, strict byte 00004h                ; 83 ff 04
-    jbe short 08845h                          ; 76 0f
-    push di                                   ; 57
+    les bx, [bp+004h]                         ; c4 5e 04
+    movzx bx, byte [es:bx+008h]               ; 26 0f b6 5f 08
+    sub bx, strict byte 0000ch                ; 83 eb 0c
+    cmp bx, strict byte 00004h                ; 83 fb 04
+    jbe short 0888ah                          ; 76 0f
+    push bx                                   ; 53
     push 00c66h                               ; 68 66 0c
     push 00c78h                               ; 68 78 0c
     push strict byte 00007h                   ; 6a 07
-    call 01972h                               ; e8 30 91
+    call 01972h                               ; e8 eb 90
     add sp, strict byte 00008h                ; 83 c4 08
-    les bx, [bp+004h]                         ; c4 5e 04
-    mov dx, word [es:bx+001eeh]               ; 26 8b 97 ee 01
+    les di, [bp+004h]                         ; c4 7e 04
+    mov dx, word [es:di+001eeh]               ; 26 8b 95 ee 01
     xor ax, ax                                ; 31 c0
-    call 0810eh                               ; e8 bc f8
+    call 08139h                               ; e8 a2 f8
     mov es, [bp+006h]                         ; 8e 46 06
-    add di, bx                                ; 01 df
-    movzx bx, byte [es:di+001e9h]             ; 26 0f b6 9d e9 01
-    mov di, word [bp+004h]                    ; 8b 7e 04
-    mov dx, word [es:di+001eeh]               ; 26 8b 95 ee 01
+    add bx, di                                ; 01 fb
+    movzx bx, byte [es:bx+001e9h]             ; 26 0f b6 9f e9 01
+    mov si, di                                ; 89 fe
+    mov dx, word [es:si+001eeh]               ; 26 8b 94 ee 01
     xor ax, ax                                ; 31 c0
-    call 0861bh                               ; e8 b1 fd
+    call 08660h                               ; e8 b2 fd
     mov bx, strict word 00025h                ; bb 25 00
     mov ax, di                                ; 89 f8
     mov dx, word [bp+006h]                    ; 8b 56 06
-    call 0830dh                               ; e8 98 fa
+    call 08338h                               ; e8 7f fa
+    mov bx, ax                                ; 89 c3
     mov es, [bp+006h]                         ; 8e 46 06
-    mov bx, di                                ; 89 fb
-    mov ax, word [es:bx+00ah]                 ; 26 8b 47 0a
-    mov word [es:bx+014h], ax                 ; 26 89 47 14
+    mov ax, word [es:di+00ah]                 ; 26 8b 45 0a
+    mov word [es:si+014h], ax                 ; 26 89 44 14
     mov cx, ax                                ; 89 c1
     sal cx, 009h                              ; c1 e1 09
     shr cx, 1                                 ; d1 e9
     mov di, word [es:di+004h]                 ; 26 8b 7d 04
-    mov ax, word [es:bx+006h]                 ; 26 8b 47 06
+    mov ax, word [es:si+006h]                 ; 26 8b 44 06
     mov si, di                                ; 89 fe
     mov dx, ax                                ; 89 c2
     mov es, ax                                ; 8e c0
@@ -12704,17 +12734,17 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     mov ds, dx                                ; 8e da
     rep movsw                                 ; f3 a5
     pop DS                                    ; 1f
-    mov es, [bp+006h]                         ; 8e 46 06
-    mov dx, word [es:bx+001eeh]               ; 26 8b 97 ee 01
-    xor ax, ax                                ; 31 c0
-    call 08125h                               ; e8 7b f8
+    les si, [bp+004h]                         ; c4 76 04
+    mov dx, word [es:si+001eeh]               ; 26 8b 94 ee 01
     xor ax, ax                                ; 31 c0
+    call 08150h                               ; e8 62 f8
+    mov ax, bx                                ; 89 d8
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 00004h                               ; c2 04 00
- at ahci_write_sectors:                         ; 0xf88b5 LB 0x70
+ at ahci_write_sectors:                         ; 0xf88f9 LB 0x72
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -12724,39 +12754,40 @@ ahci_port_init_:                             ; 0xf861b LB 0x206
     movzx bx, byte [es:si+008h]               ; 26 0f b6 5c 08
     sub bx, strict byte 0000ch                ; 83 eb 0c
     cmp bx, strict byte 00004h                ; 83 fb 04
-    jbe short 088ddh                          ; 76 0f
+    jbe short 08921h                          ; 76 0f
     push bx                                   ; 53
     push 00c97h                               ; 68 97 0c
     push 00c78h                               ; 68 78 0c
     push strict byte 00007h                   ; 6a 07
-    call 01972h                               ; e8 98 90
+    call 01972h                               ; e8 54 90
     add sp, strict byte 00008h                ; 83 c4 08
     mov es, cx                                ; 8e c1
     mov dx, word [es:si+001eeh]               ; 26 8b 94 ee 01
     xor ax, ax                                ; 31 c0
-    call 0810eh                               ; e8 25 f8
+    call 08139h                               ; e8 0c f8
     mov es, cx                                ; 8e c1
     add bx, si                                ; 01 f3
     movzx bx, byte [es:bx+001e9h]             ; 26 0f b6 9f e9 01
     mov dx, word [es:si+001eeh]               ; 26 8b 94 ee 01
     xor ax, ax                                ; 31 c0
-    call 0861bh                               ; e8 1e fd
+    call 08660h                               ; e8 1f fd
     mov bx, strict word 00035h                ; bb 35 00
     mov ax, si                                ; 89 f0
     mov dx, cx                                ; 89 ca
-    call 0830dh                               ; e8 06 fa
+    call 08338h                               ; e8 ed f9
+    mov bx, ax                                ; 89 c3
     mov es, cx                                ; 8e c1
     mov dx, word [es:si+00ah]                 ; 26 8b 54 0a
     mov word [es:si+014h], dx                 ; 26 89 54 14
     mov dx, word [es:si+001eeh]               ; 26 8b 94 ee 01
     xor ax, ax                                ; 31 c0
-    call 08125h                               ; e8 0a f8
-    xor ax, ax                                ; 31 c0
+    call 08150h                               ; e8 ef f7
+    mov ax, bx                                ; 89 d8
     lea sp, [bp-002h]                         ; 8d 66 fe
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 00004h                               ; c2 04 00
-ahci_cmd_packet_:                            ; 0xf8925 LB 0x173
+ahci_cmd_packet_:                            ; 0xf896b LB 0x173
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -12768,30 +12799,30 @@ ahci_cmd_packet_:                            ; 0xf8925 LB 0x173
     mov word [bp-010h], cx                    ; 89 4e f0
     mov dx, strict word 0000eh                ; ba 0e 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0166ch                               ; e8 2c 8d
+    call 0166ch                               ; e8 e6 8c
     mov si, 00122h                            ; be 22 01
     mov word [bp-008h], ax                    ; 89 46 f8
     cmp byte [bp+00ah], 002h                  ; 80 7e 0a 02
-    jne short 0896bh                          ; 75 1f
+    jne short 089b1h                          ; 75 1f
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 da 8f
+    call 01931h                               ; e8 94 8f
     push 00caah                               ; 68 aa 0c
     push 00cbah                               ; 68 ba 0c
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 10 90
+    call 01972h                               ; e8 ca 8f
     add sp, strict byte 00006h                ; 83 c4 06
     mov ax, strict word 00001h                ; b8 01 00
-    jmp near 08a8fh                           ; e9 24 01
+    jmp near 08ad5h                           ; e9 24 01
     test byte [bp+004h], 001h                 ; f6 46 04 01
-    jne short 08965h                          ; 75 f4
+    jne short 089abh                          ; 75 f4
     mov ax, word [bp+006h]                    ; 8b 46 06
     mov dx, word [bp+008h]                    ; 8b 56 08
     mov cx, strict word 00008h                ; b9 08 00
     sal ax, 1                                 ; d1 e0
     rcl dx, 1                                 ; d1 d2
-    loop 0897ah                               ; e2 fa
+    loop 089c0h                               ; e2 fa
     mov es, [bp-008h]                         ; 8e 46 f8
     mov word [es:si], ax                      ; 26 89 04
     mov word [es:si+002h], dx                 ; 26 89 54 02
@@ -12803,7 +12834,7 @@ ahci_cmd_packet_:                            ; 0xf8925 LB 0x173
     mov ax, word [bp+006h]                    ; 8b 46 06
     mov dx, word [bp+008h]                    ; 8b 56 08
     xor cx, cx                                ; 31 c9
-    call 096f0h                               ; e8 49 0d
+    call 09740h                               ; e8 53 0d
     mov word [es:si+00ah], ax                 ; 26 89 44 0a
     xor di, di                                ; 31 ff
     mov ax, word [es:si+001eeh]               ; 26 8b 84 ee 01
@@ -12813,28 +12844,28 @@ ahci_cmd_packet_:                            ; 0xf8925 LB 0x173
     sub word [bp-014h], strict byte 0000ch    ; 83 6e ec 0c
     xor ax, ax                                ; 31 c0
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 0810eh                               ; e8 47 f7
+    call 08139h                               ; e8 2c f7
     mov es, [bp-008h]                         ; 8e 46 f8
     mov bx, word [bp-014h]                    ; 8b 5e ec
     add bx, si                                ; 01 f3
     movzx bx, byte [es:bx+001e9h]             ; 26 0f b6 9f e9 01
     mov dx, word [es:si+001eeh]               ; 26 8b 94 ee 01
     xor ax, ax                                ; 31 c0
-    call 0861bh                               ; e8 3c fc
+    call 08660h                               ; e8 3b fc
     movzx ax, byte [bp-006h]                  ; 0f b6 46 fa
     push ax                                   ; 50
     mov bx, word [bp-012h]                    ; 8b 5e ee
     mov cx, word [bp-010h]                    ; 8b 4e f0
     mov ax, 000c0h                            ; b8 c0 00
     mov dx, word [bp-00ah]                    ; 8b 56 f6
-    call 09767h                               ; e8 74 0d
+    call 097b7h                               ; e8 7e 0d
     mov es, [bp-008h]                         ; 8e 46 f8
     mov word [es:si+014h], di                 ; 26 89 7c 14
     mov word [es:si+016h], di                 ; 26 89 7c 16
     mov word [es:si+018h], di                 ; 26 89 7c 18
     mov ax, word [es:si+01ah]                 ; 26 8b 44 1a
     test ax, ax                               ; 85 c0
-    je short 08a31h                           ; 74 27
+    je short 08a77h                           ; 74 27
     dec ax                                    ; 48
     mov es, [bp-00ah]                         ; 8e 46 f6
     mov word [es:di+0010ch], ax               ; 26 89 85 0c 01
@@ -12847,7 +12878,7 @@ ahci_cmd_packet_:                            ; 0xf8925 LB 0x173
     mov bx, 000a0h                            ; bb a0 00
     mov ax, si                                ; 89 f0
     mov dx, word [bp-008h]                    ; 8b 56 f8
-    call 0830dh                               ; e8 d1 f8
+    call 08338h                               ; e8 b6 f8
     les bx, [bp-00eh]                         ; c4 5e f2
     mov ax, word [es:bx+004h]                 ; 26 8b 47 04
     mov dx, word [es:bx+006h]                 ; 26 8b 57 06
@@ -12870,20 +12901,20 @@ ahci_cmd_packet_:                            ; 0xf8925 LB 0x173
     pop DS                                    ; 1f
     mov ax, word [bp-00eh]                    ; 8b 46 f2
     mov dx, word [bp-00ch]                    ; 8b 56 f4
-    call 08125h                               ; e8 aa f6
+    call 08150h                               ; e8 8f f6
     les bx, [bp-00eh]                         ; c4 5e f2
     mov ax, word [es:bx+006h]                 ; 26 8b 47 06
     or ax, word [es:bx+004h]                  ; 26 0b 47 04
-    jne short 08a8dh                          ; 75 05
+    jne short 08ad3h                          ; 75 05
     mov ax, strict word 00004h                ; b8 04 00
-    jmp short 08a8fh                          ; eb 02
+    jmp short 08ad5h                          ; eb 02
     xor ax, ax                                ; 31 c0
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 0000ch                               ; c2 0c 00
-ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
+ahci_port_detect_device_:                    ; 0xf8ade LB 0x451
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -12895,10 +12926,10 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov byte [bp-008h], bl                    ; 88 5e f8
     movzx di, bl                              ; 0f b6 fb
     mov bx, di                                ; 89 fb
-    call 0861bh                               ; e8 69 fb
+    call 08660h                               ; e8 68 fb
     mov dx, strict word 0000eh                ; ba 0e 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0166ch                               ; e8 b1 8b
+    call 0166ch                               ; e8 6b 8b
     mov word [bp-010h], 00122h                ; c7 46 f0 22 01
     mov word [bp-00eh], ax                    ; 89 46 f2
     sal di, 007h                              ; c1 e7 07
@@ -12967,9 +12998,9 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     push strict byte 00000h                   ; 6a 00
     mov bx, strict word 0000fh                ; bb 0f 00
     xor cx, cx                                ; 31 c9
-    call 081ffh                               ; e8 9a f6
+    call 0822ah                               ; e8 7f f6
     test ax, ax                               ; 85 c0
-    je near 08ee1h                            ; 0f 84 76 03
+    je near 08f27h                            ; 0f 84 76 03
     movzx ax, byte [bp-008h]                  ; 0f b6 46 f8
     sal ax, 007h                              ; c1 e0 07
     mov word [bp-016h], ax                    ; 89 46 ea
@@ -12997,17 +13028,17 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     push strict byte 00000h                   ; 6a 00
     mov bx, strict word 0000fh                ; bb 0f 00
     xor cx, cx                                ; 31 c9
-    call 081ffh                               ; e8 4e f6
+    call 0822ah                               ; e8 33 f6
     cmp ax, strict word 00001h                ; 3d 01 00
-    je short 08b6bh                           ; 74 b5
+    je short 08bb1h                           ; 74 b5
     push strict byte 00000h                   ; 6a 00
     mov bx, strict word 0000fh                ; bb 0f 00
     xor cx, cx                                ; 31 c9
     mov ax, di                                ; 89 f8
     mov dx, word [bp-01ah]                    ; 8b 56 e6
-    call 081ffh                               ; e8 3a f6
+    call 0822ah                               ; e8 1f f6
     cmp ax, strict word 00003h                ; 3d 03 00
-    jne near 08ee1h                           ; 0f 85 15 03
+    jne near 08f27h                           ; 0f 85 15 03
     mov ax, word [bp-016h]                    ; 8b 46 ea
     add ax, 00130h                            ; 05 30 01
     cwd                                       ; 99
@@ -13034,14 +13065,14 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov al, byte [es:bx+001edh]               ; 26 8a 87 ed 01
     mov byte [bp-00ch], al                    ; 88 46 f4
     cmp AL, strict byte 004h                  ; 3c 04
-    jnc near 08ee1h                           ; 0f 83 cf 02
+    jnc near 08f27h                           ; 0f 83 cf 02
     mov dx, word [bp-016h]                    ; 8b 56 ea
     add dx, 00118h                            ; 81 c2 18 01
     mov es, [bp-012h]                         ; 8e 46 ee
     mov ax, word [es:si+00260h]               ; 26 8b 84 60 02
     mov bx, strict word 00010h                ; bb 10 00
     xor cx, cx                                ; 31 c9
-    call 0813ch                               ; e8 13 f5
+    call 08167h                               ; e8 f8 f4
     mov ax, word [bp-016h]                    ; 8b 46 ea
     add ax, 00124h                            ; 05 24 01
     cwd                                       ; 99
@@ -13065,9 +13096,9 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov cl, byte [bp-00ch]                    ; 8a 4e f4
     add cl, 00ch                              ; 80 c1 0c
     test dx, dx                               ; 85 d2
-    jne near 08e3dh                           ; 0f 85 d8 01
+    jne near 08e83h                           ; 0f 85 d8 01
     cmp ax, 00101h                            ; 3d 01 01
-    jne near 08e3dh                           ; 0f 85 d1 01
+    jne near 08e83h                           ; 0f 85 d1 01
     les bx, [bp-010h]                         ; c4 5e f0
     db  066h, 026h, 0c7h, 007h, 000h, 000h, 000h, 000h
     ; mov dword [es:bx], strict dword 000000000h ; 66 26 c7 07 00 00 00 00
@@ -13079,7 +13110,7 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov bx, 000ech                            ; bb ec 00
     mov ax, word [bp-010h]                    ; 8b 46 f0
     mov dx, es                                ; 8c c2
-    call 0830dh                               ; e8 76 f6
+    call 08338h                               ; e8 5b f6
     mov byte [bp-00ah], cl                    ; 88 4e f6
     test byte [bp-00226h], 080h               ; f6 86 da fd 80
     db  00fh, 095h, 0c0h
@@ -13096,9 +13127,9 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov word [bp-014h], ax                    ; 89 46 ec
     mov di, word [bp-001ach]                  ; 8b be 54 fe
     cmp di, 00fffh                            ; 81 ff ff 0f
-    jne short 08cdch                          ; 75 10
+    jne short 08d22h                          ; 75 10
     cmp ax, strict word 0ffffh                ; 3d ff ff
-    jne short 08cdch                          ; 75 0b
+    jne short 08d22h                          ; 75 0b
     mov ax, word [bp-0015eh]                  ; 8b 86 a2 fe
     mov word [bp-014h], ax                    ; 89 46 ec
     mov di, word [bp-0015ch]                  ; 8b be a4 fe
@@ -13127,62 +13158,62 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov word [es:si+030h], ax                 ; 26 89 44 30
     mov al, byte [bp-00ch]                    ; 8a 46 f4
     cmp AL, strict byte 001h                  ; 3c 01
-    jc short 08d47h                           ; 72 0c
-    jbe short 08d4fh                          ; 76 12
+    jc short 08d8dh                           ; 72 0c
+    jbe short 08d95h                          ; 76 12
     cmp AL, strict byte 003h                  ; 3c 03
-    je short 08d57h                           ; 74 16
+    je short 08d9dh                           ; 74 16
     cmp AL, strict byte 002h                  ; 3c 02
-    je short 08d53h                           ; 74 0e
-    jmp short 08da0h                          ; eb 59
+    je short 08d99h                           ; 74 0e
+    jmp short 08de6h                          ; eb 59
     test al, al                               ; 84 c0
-    jne short 08da0h                          ; 75 55
+    jne short 08de6h                          ; 75 55
     mov DL, strict byte 040h                  ; b2 40
-    jmp short 08d59h                          ; eb 0a
+    jmp short 08d9fh                          ; eb 0a
     mov DL, strict byte 048h                  ; b2 48
-    jmp short 08d59h                          ; eb 06
+    jmp short 08d9fh                          ; eb 06
     mov DL, strict byte 050h                  ; b2 50
-    jmp short 08d59h                          ; eb 02
+    jmp short 08d9fh                          ; eb 02
     mov DL, strict byte 058h                  ; b2 58
     mov al, dl                                ; 88 d0
     add AL, strict byte 007h                  ; 04 07
     movzx bx, al                              ; 0f b6 d8
     mov ax, bx                                ; 89 d8
-    call 016ach                               ; e8 47 89
+    call 016ach                               ; e8 01 89
     test al, al                               ; 84 c0
-    je short 08da0h                           ; 74 37
+    je short 08de6h                           ; 74 37
     mov al, dl                                ; 88 d0
     db  0feh, 0c0h
     ; inc al                                    ; fe c0
     xor ah, ah                                ; 30 e4
-    call 016ach                               ; e8 3a 89
+    call 016ach                               ; e8 f4 88
     xor ah, ah                                ; 30 e4
     mov si, ax                                ; 89 c6
     sal si, 008h                              ; c1 e6 08
     movzx ax, dl                              ; 0f b6 c2
-    call 016ach                               ; e8 2d 89
+    call 016ach                               ; e8 e7 88
     xor ah, ah                                ; 30 e4
     add ax, si                                ; 01 f0
     mov word [bp-024h], ax                    ; 89 46 dc
     mov al, dl                                ; 88 d0
     add AL, strict byte 002h                  ; 04 02
     xor ah, ah                                ; 30 e4
-    call 016ach                               ; e8 1d 89
+    call 016ach                               ; e8 d7 88
     xor ah, ah                                ; 30 e4
     mov word [bp-026h], ax                    ; 89 46 da
     mov ax, bx                                ; 89 d8
-    call 016ach                               ; e8 13 89
+    call 016ach                               ; e8 cd 88
     xor ah, ah                                ; 30 e4
     mov word [bp-022h], ax                    ; 89 46 de
-    jmp short 08dadh                          ; eb 0d
+    jmp short 08df3h                          ; eb 0d
     mov bx, word [bp-014h]                    ; 8b 5e ec
     mov cx, di                                ; 89 f9
     mov dx, ss                                ; 8c d2
     lea ax, [bp-026h]                         ; 8d 46 da
-    call 055b6h                               ; e8 09 c8
+    call 055b6h                               ; e8 c3 c7
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 79 8b
+    call 01931h                               ; e8 33 8b
     push di                                   ; 57
     push word [bp-014h]                       ; ff 76 ec
     mov ax, word [bp-022h]                    ; 8b 46 de
@@ -13199,7 +13230,7 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     push ax                                   ; 50
     push 00cdah                               ; 68 da 0c
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 91 8b
+    call 01972h                               ; e8 4b 8b
     add sp, strict byte 00018h                ; 83 c4 18
     movzx ax, byte [bp-00ah]                  ; 0f b6 46 f6
     imul ax, ax, strict byte 00018h           ; 6b c0 18
@@ -13228,18 +13259,18 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov byte [es:bx+0019eh], al               ; 26 88 87 9e 01
     mov dx, strict word 00075h                ; ba 75 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 01650h                               ; e8 24 88
+    call 01650h                               ; e8 de 87
     db  0feh, 0c0h
     ; inc al                                    ; fe c0
     movzx bx, al                              ; 0f b6 d8
     mov dx, strict word 00075h                ; ba 75 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0165eh                               ; e8 24 88
-    jmp near 08ed3h                           ; e9 96 00
+    call 0165eh                               ; e8 de 87
+    jmp near 08f19h                           ; e9 96 00
     cmp dx, 0eb14h                            ; 81 fa 14 eb
-    jne near 08ed3h                           ; 0f 85 8e 00
+    jne near 08f19h                           ; 0f 85 8e 00
     cmp ax, 00101h                            ; 3d 01 01
-    jne near 08ed3h                           ; 0f 85 87 00
+    jne near 08f19h                           ; 0f 85 87 00
     les bx, [bp-010h]                         ; c4 5e f0
     db  066h, 026h, 0c7h, 007h, 000h, 000h, 000h, 000h
     ; mov dword [es:bx], strict dword 000000000h ; 66 26 c7 07 00 00 00 00
@@ -13251,7 +13282,7 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     mov bx, 000a1h                            ; bb a1 00
     mov ax, word [bp-010h]                    ; 8b 46 f0
     mov dx, es                                ; 8c c2
-    call 0830dh                               ; e8 96 f4
+    call 08338h                               ; e8 7b f4
     test byte [bp-00226h], 080h               ; f6 86 da fd 80
     db  00fh, 095h, 0c0h
     ; setne al                                  ; 0f 95 c0
@@ -13290,7 +13321,7 @@ ahci_port_detect_device_:                    ; 0xf8a98 LB 0x451
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_mem_alloc_:                             ; 0xf8ee9 LB 0x43
+ahci_mem_alloc_:                             ; 0xf8f2f LB 0x43
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -13300,25 +13331,25 @@ ahci_mem_alloc_:                             ; 0xf8ee9 LB 0x43
     push di                                   ; 57
     mov dx, 00413h                            ; ba 13 04
     xor ax, ax                                ; 31 c0
-    call 0166ch                               ; e8 73 87
+    call 0166ch                               ; e8 2d 87
     test ax, ax                               ; 85 c0
-    je short 08f22h                           ; 74 25
+    je short 08f68h                           ; 74 25
     dec ax                                    ; 48
     mov bx, ax                                ; 89 c3
     xor dx, dx                                ; 31 d2
     mov cx, strict word 0000ah                ; b9 0a 00
     sal ax, 1                                 ; d1 e0
     rcl dx, 1                                 ; d1 d2
-    loop 08f05h                               ; e2 fa
+    loop 08f4bh                               ; e2 fa
     mov si, ax                                ; 89 c6
     mov di, dx                                ; 89 d7
     mov cx, strict word 00004h                ; b9 04 00
     shr di, 1                                 ; d1 ef
     rcr si, 1                                 ; d1 de
-    loop 08f12h                               ; e2 fa
+    loop 08f58h                               ; e2 fa
     mov dx, 00413h                            ; ba 13 04
     xor ax, ax                                ; 31 c0
-    call 0167ah                               ; e8 5a 87
+    call 0167ah                               ; e8 14 87
     mov ax, si                                ; 89 f0
     lea sp, [bp-00ah]                         ; 8d 66 f6
     pop di                                    ; 5f
@@ -13328,7 +13359,7 @@ ahci_mem_alloc_:                             ; 0xf8ee9 LB 0x43
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-ahci_hba_init_:                              ; 0xf8f2c LB 0x125
+ahci_hba_init_:                              ; 0xf8f72 LB 0x125
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -13340,7 +13371,7 @@ ahci_hba_init_:                              ; 0xf8f2c LB 0x125
     mov si, ax                                ; 89 c6
     mov dx, strict word 0000eh                ; ba 0e 00
     mov ax, strict word 00040h                ; b8 40 00
-    call 0166ch                               ; e8 2a 87
+    call 0166ch                               ; e8 e4 86
     mov bx, 00122h                            ; bb 22 01
     mov word [bp-010h], ax                    ; 89 46 f0
     mov ax, strict word 00010h                ; b8 10 00
@@ -13357,10 +13388,10 @@ ahci_hba_init_:                              ; 0xf8f2c LB 0x125
     ; mov dx, ax                                ; 8b d0
     shr eax, 010h                             ; 66 c1 e8 10
     xchg dx, ax                               ; 92
-    call 08ee9h                               ; e8 82 ff
+    call 08f2fh                               ; e8 82 ff
     mov di, ax                                ; 89 c7
     test ax, ax                               ; 85 c0
-    je near 09030h                            ; 0f 84 c1 00
+    je near 09076h                            ; 0f 84 c1 00
     mov es, [bp-010h]                         ; 8e 46 f0
     mov word [es:bx+001eeh], di               ; 26 89 bf ee 01
     mov byte [es:bx+001edh], 000h             ; 26 c6 87 ed 01 00
@@ -13374,7 +13405,7 @@ ahci_hba_init_:                              ; 0xf8f2c LB 0x125
     xor cx, cx                                ; 31 c9
     mov dx, strict word 00004h                ; ba 04 00
     mov ax, si                                ; 89 f0
-    call 0813ch                               ; e8 99 f1
+    call 08167h                               ; e8 7e f1
     mov ax, strict word 00004h                ; b8 04 00
     xor cx, cx                                ; 31 c9
     mov dx, si                                ; 89 f2
@@ -13391,7 +13422,7 @@ ahci_hba_init_:                              ; 0xf8f2c LB 0x125
     shr eax, 010h                             ; 66 c1 e8 10
     xchg dx, ax                               ; 92
     test AL, strict byte 001h                 ; a8 01
-    jne short 08fa3h                          ; 75 de
+    jne short 08fe9h                          ; 75 de
     xor ax, ax                                ; 31 c0
     xor cx, cx                                ; 31 c9
     mov dx, si                                ; 89 f2
@@ -13409,35 +13440,35 @@ ahci_hba_init_:                              ; 0xf8f2c LB 0x125
     push strict byte 00000h                   ; 6a 00
     mov bx, strict word 0001fh                ; bb 1f 00
     xor cx, cx                                ; 31 c9
-    call 081ffh                               ; e8 16 f2
+    call 0822ah                               ; e8 fb f1
     db  0feh, 0c0h
     ; inc al                                    ; fe c0
     mov byte [bp-00eh], al                    ; 88 46 f2
     mov byte [bp-00ch], 000h                  ; c6 46 f4 00
-    jmp short 08ffdh                          ; eb 09
+    jmp short 09043h                          ; eb 09
     inc byte [bp-00ch]                        ; fe 46 f4
     cmp byte [bp-00ch], 020h                  ; 80 7e f4 20
-    jnc short 0902eh                          ; 73 31
+    jnc short 09074h                          ; 73 31
     movzx cx, byte [bp-00ch]                  ; 0f b6 4e f4
     mov ax, strict word 00001h                ; b8 01 00
     xor dx, dx                                ; 31 d2
-    jcxz 0900eh                               ; e3 06
+    jcxz 09054h                               ; e3 06
     sal ax, 1                                 ; d1 e0
     rcl dx, 1                                 ; d1 d2
-    loop 09008h                               ; e2 fa
+    loop 0904eh                               ; e2 fa
     mov bx, ax                                ; 89 c3
     mov cx, dx                                ; 89 d1
     mov dx, strict word 0000ch                ; ba 0c 00
     mov ax, si                                ; 89 f0
-    call 081c6h                               ; e8 ac f1
+    call 081f1h                               ; e8 91 f1
     test al, al                               ; 84 c0
-    je short 08ff4h                           ; 74 d6
+    je short 0903ah                           ; 74 d6
     movzx bx, byte [bp-00ch]                  ; 0f b6 5e f4
     xor ax, ax                                ; 31 c0
     mov dx, di                                ; 89 fa
-    call 08a98h                               ; e8 6f fa
+    call 08adeh                               ; e8 6f fa
     dec byte [bp-00eh]                        ; fe 4e f2
-    jne short 08ff4h                          ; 75 c6
+    jne short 0903ah                          ; 75 c6
     xor ax, ax                                ; 31 c0
     lea sp, [bp-00ah]                         ; 8d 66 f6
     pop di                                    ; 5f
@@ -13447,9 +13478,9 @@ ahci_hba_init_:                              ; 0xf8f2c LB 0x125
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-    db  00bh, 005h, 004h, 003h, 002h, 001h, 000h, 020h, 091h, 0feh, 090h, 004h, 091h, 00ah, 091h, 010h
-    db  091h, 016h, 091h, 01ch, 091h, 020h, 091h
-_ahci_init:                                  ; 0xf9051 LB 0xfe
+    db  00bh, 005h, 004h, 003h, 002h, 001h, 000h, 066h, 091h, 044h, 091h, 04ah, 091h, 050h, 091h, 056h
+    db  091h, 05ch, 091h, 062h, 091h, 066h, 091h
+_ahci_init:                                  ; 0xf9097 LB 0xfe
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -13457,10 +13488,10 @@ _ahci_init:                                  ; 0xf9051 LB 0xfe
     sub sp, strict byte 00006h                ; 83 ec 06
     mov ax, 00601h                            ; b8 01 06
     mov dx, strict word 00001h                ; ba 01 00
-    call 0956fh                               ; e8 0d 05
+    call 095b5h                               ; e8 0d 05
     mov dx, ax                                ; 89 c2
     cmp ax, strict word 0ffffh                ; 3d ff ff
-    je near 09148h                            ; 0f 84 dd 00
+    je near 0918eh                            ; 0f 84 dd 00
     xor al, al                                ; 30 c0
     shr ax, 008h                              ; c1 e8 08
     mov byte [bp-00ah], al                    ; 88 46 f6
@@ -13468,127 +13499,128 @@ _ahci_init:                                  ; 0xf9051 LB 0xfe
     xor dh, dh                                ; 30 f6
     xor ah, ah                                ; 30 e4
     mov bx, strict word 00034h                ; bb 34 00
-    call 0959ah                               ; e8 1a 05
+    call 095e0h                               ; e8 1a 05
     mov cl, al                                ; 88 c1
     test cl, cl                               ; 84 c9
-    je short 090a9h                           ; 74 23
+    je short 090efh                           ; 74 23
     movzx bx, cl                              ; 0f b6 d9
     movzx di, byte [bp-008h]                  ; 0f b6 7e f8
     movzx si, byte [bp-00ah]                  ; 0f b6 76 f6
     mov dx, di                                ; 89 fa
     mov ax, si                                ; 89 f0
-    call 0959ah                               ; e8 02 05
+    call 095e0h                               ; e8 02 05
     cmp AL, strict byte 012h                  ; 3c 12
-    je short 090a9h                           ; 74 0d
+    je short 090efh                           ; 74 0d
     mov al, cl                                ; 88 c8
     db  0feh, 0c0h
     ; inc al                                    ; fe c0
     movzx bx, al                              ; 0f b6 d8
     mov dx, di                                ; 89 fa
     mov ax, si                                ; 89 f0
-    jmp short 0907dh                          ; eb d4
+    jmp short 090c3h                          ; eb d4
     test cl, cl                               ; 84 c9
-    je near 09148h                            ; 0f 84 99 00
+    je near 0918eh                            ; 0f 84 99 00
     add cl, 002h                              ; 80 c1 02
     movzx bx, cl                              ; 0f b6 d9
     movzx di, byte [bp-008h]                  ; 0f b6 7e f8
     movzx si, byte [bp-00ah]                  ; 0f b6 76 f6
     mov dx, di                                ; 89 fa
     mov ax, si                                ; 89 f0
-    call 0959ah                               ; e8 d6 04
+    call 095e0h                               ; e8 d6 04
     cmp AL, strict byte 010h                  ; 3c 10
-    jne near 09148h                           ; 0f 85 7e 00
+    jne near 0918eh                           ; 0f 85 7e 00
     mov byte [bp-006h], 000h                  ; c6 46 fa 00
     mov al, cl                                ; 88 c8
     add AL, strict byte 002h                  ; 04 02
     movzx bx, al                              ; 0f b6 d8
     mov dx, di                                ; 89 fa
     mov ax, si                                ; 89 f0
-    call 095beh                               ; e8 e2 04
+    call 09604h                               ; e8 e2 04
     mov dx, ax                                ; 89 c2
     and ax, strict word 0000fh                ; 25 0f 00
     sub ax, strict word 00004h                ; 2d 04 00
     cmp ax, strict word 0000bh                ; 3d 0b 00
-    jnbe short 09120h                         ; 77 37
+    jnbe short 09166h                         ; 77 37
     push CS                                   ; 0e
     pop ES                                    ; 07
     mov cx, strict word 00008h                ; b9 08 00
-    mov di, 0903ah                            ; bf 3a 90
+    mov di, 09080h                            ; bf 80 90
     repne scasb                               ; f2 ae
     sal cx, 1                                 ; d1 e1
     mov di, cx                                ; 89 cf
-    mov ax, word [cs:di-06fbfh]               ; 2e 8b 85 41 90
+    mov ax, word [cs:di-06f79h]               ; 2e 8b 85 87 90
     jmp ax                                    ; ff e0
     mov byte [bp-006h], 010h                  ; c6 46 fa 10
-    jmp short 09120h                          ; eb 1c
+    jmp short 09166h                          ; eb 1c
     mov byte [bp-006h], 014h                  ; c6 46 fa 14
-    jmp short 09120h                          ; eb 16
+    jmp short 09166h                          ; eb 16
     mov byte [bp-006h], 018h                  ; c6 46 fa 18
-    jmp short 09120h                          ; eb 10
+    jmp short 09166h                          ; eb 10
     mov byte [bp-006h], 01ch                  ; c6 46 fa 1c
-    jmp short 09120h                          ; eb 0a
+    jmp short 09166h                          ; eb 0a
     mov byte [bp-006h], 020h                  ; c6 46 fa 20
-    jmp short 09120h                          ; eb 04
+    jmp short 09166h                          ; eb 04
     mov byte [bp-006h], 024h                  ; c6 46 fa 24
     mov si, dx                                ; 89 d6
     shr si, 004h                              ; c1 ee 04
     sal si, 002h                              ; c1 e6 02
     mov al, byte [bp-006h]                    ; 8a 46 fa
     test al, al                               ; 84 c0
-    je short 09148h                           ; 74 19
+    je short 0918eh                           ; 74 19
     movzx bx, al                              ; 0f b6 d8
     movzx dx, byte [bp-008h]                  ; 0f b6 56 f8
     movzx ax, byte [bp-00ah]                  ; 0f b6 46 f6
-    call 095e0h                               ; e8 a3 04
+    call 09626h                               ; e8 a3 04
     test AL, strict byte 001h                 ; a8 01
-    je short 09148h                           ; 74 07
+    je short 0918eh                           ; 74 07
     and AL, strict byte 0f0h                  ; 24 f0
     add ax, si                                ; 01 f0
-    call 08f2ch                               ; e8 e4 fd
+    call 08f72h                               ; e8 e4 fd
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-apm_out_str_:                                ; 0xf914f LB 0x39
+apm_out_str_:                                ; 0xf9195 LB 0x39
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
     mov bx, ax                                ; 89 c3
     cmp byte [bx], 000h                       ; 80 3f 00
-    je short 09164h                           ; 74 0a
+    je short 091aah                           ; 74 0a
     mov al, byte [bx]                         ; 8a 07
     out DX, AL                                ; ee
     inc bx                                    ; 43
     mov al, byte [bx]                         ; 8a 07
     db  00ah, 0c0h
     ; or al, al                                 ; 0a c0
-    jne short 0915ch                          ; 75 f8
+    jne short 091a2h                          ; 75 f8
     lea sp, [bp-002h]                         ; 8d 66 fe
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-    stosw                                     ; ab
-    xchg cx, ax                               ; 91
-    jnbe short 09100h                         ; 77 92
-    mov bp, 0d891h                            ; bd 91 d8
+    db  0f1h
     xchg cx, ax                               ; 91
-    jnbe short 09106h                         ; 77 92
-    add dx, word [bp+si-06d89h]               ; 03 92 77 92
-    or byte [bp+si-06db4h], dl                ; 08 92 4c 92
-    dec sp                                    ; 4c
+    mov bp, 00392h                            ; bd 92 03
     xchg dx, ax                               ; 92
-    dec sp                                    ; 4c
+    push DS                                   ; 1e
     xchg dx, ax                               ; 92
-    inc di                                    ; 47
+    mov bp, 04992h                            ; bd 92 49
     xchg dx, ax                               ; 92
-    dec sp                                    ; 4c
+    mov bp, 04e92h                            ; bd 92 4e
     xchg dx, ax                               ; 92
-    dec sp                                    ; 4c
     xchg dx, ax                               ; 92
-    inc ax                                    ; 40
     xchg dx, ax                               ; 92
-_apm_function:                               ; 0xf9188 LB 0xf5
+    xchg dx, ax                               ; 92
+    xchg dx, ax                               ; 92
+    xchg dx, ax                               ; 92
+    xchg dx, ax                               ; 92
+    lea dx, [bp+si-06d6eh]                    ; 8d 92 92 92
+    xchg dx, ax                               ; 92
+    xchg dx, ax                               ; 92
+    db  086h
+    xchg dx, ax                               ; 92
+_apm_function:                               ; 0xf91ce LB 0xf5
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -13596,23 +13628,23 @@ _apm_function:                               ; 0xf9188 LB 0xf5
     mov ax, word [bp+012h]                    ; 8b 46 12
     xor ah, ah                                ; 30 e4
     cmp ax, strict word 0000eh                ; 3d 0e 00
-    jnbe near 0924ch                          ; 0f 87 b0 00
+    jnbe near 09292h                          ; 0f 87 b0 00
     mov bx, ax                                ; 89 c3
     add bx, ax                                ; 01 c3
     mov dx, word [bp+018h]                    ; 8b 56 18
     or dl, 001h                               ; 80 ca 01
-    jmp word [cs:bx-06e96h]                   ; 2e ff a7 6a 91
+    jmp word [cs:bx-06e50h]                   ; 2e ff a7 b0 91
     mov word [bp+012h], 00102h                ; c7 46 12 02 01
     mov word [bp+00ch], 0504dh                ; c7 46 0c 4d 50
     mov word [bp+010h], strict word 00003h    ; c7 46 10 03 00
-    jmp near 09277h                           ; e9 ba 00
+    jmp near 092bdh                           ; e9 ba 00
     mov word [bp+012h], 0f000h                ; c7 46 12 00 f0
-    mov word [bp+00ch], 097d4h                ; c7 46 0c d4 97
+    mov word [bp+00ch], 09824h                ; c7 46 0c 24 98
     mov word [bp+010h], 0f000h                ; c7 46 10 00 f0
     mov ax, strict word 0fff0h                ; b8 f0 ff
     mov word [bp+006h], ax                    ; 89 46 06
     mov word [bp+004h], ax                    ; 89 46 04
-    jmp near 09277h                           ; e9 9f 00
+    jmp near 092bdh                           ; e9 9f 00
     mov word [bp+012h], 0f000h                ; c7 46 12 00 f0
     mov word [bp+00ch], 0da40h                ; c7 46 0c 40 da
     mov ax, 0f000h                            ; b8 00 f0
@@ -13625,43 +13657,43 @@ _apm_function:                               ; 0xf9188 LB 0xf5
     sal ebx, 010h                             ; 66 c1 e3 10
     mov si, ax                                ; 89 c6
     sal esi, 010h                             ; 66 c1 e6 10
-    jmp near 09277h                           ; e9 74 00
+    jmp near 092bdh                           ; e9 74 00
     sti                                       ; fb
     hlt                                       ; f4
-    jmp near 09277h                           ; e9 6f 00
+    jmp near 092bdh                           ; e9 6f 00
     cmp word [bp+010h], strict byte 00003h    ; 83 7e 10 03
-    je short 0922dh                           ; 74 1f
+    je short 09273h                           ; 74 1f
     cmp word [bp+010h], strict byte 00002h    ; 83 7e 10 02
-    je short 09225h                           ; 74 11
+    je short 0926bh                           ; 74 11
     cmp word [bp+010h], strict byte 00001h    ; 83 7e 10 01
-    jne short 09235h                          ; 75 1b
+    jne short 0927bh                          ; 75 1b
     mov dx, 08900h                            ; ba 00 89
     mov ax, 00d12h                            ; b8 12 0d
-    call 0914fh                               ; e8 2c ff
-    jmp short 09277h                          ; eb 52
+    call 09195h                               ; e8 2c ff
+    jmp short 092bdh                          ; eb 52
     mov dx, 08900h                            ; ba 00 89
     mov ax, 00d1ah                            ; b8 1a 0d
-    jmp short 09220h                          ; eb f3
+    jmp short 09266h                          ; eb f3
     mov dx, 08900h                            ; ba 00 89
     mov ax, 00d22h                            ; b8 22 0d
-    jmp short 09220h                          ; eb eb
+    jmp short 09266h                          ; eb eb
     or ah, 00ah                               ; 80 cc 0a
     mov word [bp+012h], ax                    ; 89 46 12
     mov word [bp+018h], dx                    ; 89 56 18
-    jmp short 09277h                          ; eb 37
+    jmp short 092bdh                          ; eb 37
     mov word [bp+012h], 00102h                ; c7 46 12 02 01
-    jmp short 09277h                          ; eb 30
+    jmp short 092bdh                          ; eb 30
     or ah, 080h                               ; 80 cc 80
-    jmp short 09238h                          ; eb ec
+    jmp short 0927eh                          ; eb ec
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 da 86
+    call 01931h                               ; e8 94 86
     push word [bp+00ch]                       ; ff 76 0c
     push word [bp+012h]                       ; ff 76 12
     push 00d2bh                               ; 68 2b 0d
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 0d 87
+    call 01972h                               ; e8 c7 86
     add sp, strict byte 00008h                ; 83 c4 08
     mov ax, word [bp+012h]                    ; 8b 46 12
     xor ah, ah                                ; 30 e4
@@ -13672,7 +13704,7 @@ _apm_function:                               ; 0xf9188 LB 0xf5
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-pci16_select_reg_:                           ; 0xf927d LB 0x24
+pci16_select_reg_:                           ; 0xf92c3 LB 0x24
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -13689,7 +13721,7 @@ pci16_select_reg_:                           ; 0xf927d LB 0x24
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-pci16_find_device_:                          ; 0xf92a1 LB 0xf7
+pci16_find_device_:                          ; 0xf92e7 LB 0xf7
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -13703,49 +13735,49 @@ pci16_find_device_:                          ; 0xf92a1 LB 0xf7
     xor bx, bx                                ; 31 db
     mov byte [bp-008h], 000h                  ; c6 46 f8 00
     test bl, 007h                             ; f6 c3 07
-    jne short 092e9h                          ; 75 2d
+    jne short 0932fh                          ; 75 2d
     mov dx, strict word 0000eh                ; ba 0e 00
     mov ax, bx                                ; 89 d8
-    call 0927dh                               ; e8 b9 ff
+    call 092c3h                               ; e8 b9 ff
     mov dx, 00cfeh                            ; ba fe 0c
     in AL, DX                                 ; ec
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     mov byte [bp-006h], al                    ; 88 46 fa
     cmp AL, strict byte 0ffh                  ; 3c ff
-    jne short 092d7h                          ; 75 06
+    jne short 0931dh                          ; 75 06
     add bx, strict byte 00008h                ; 83 c3 08
-    jmp near 0936ah                           ; e9 93 00
+    jmp near 093b0h                           ; e9 93 00
     test byte [bp-006h], 080h                 ; f6 46 fa 80
-    je short 092e4h                           ; 74 07
+    je short 0932ah                           ; 74 07
     mov word [bp-00ah], strict word 00001h    ; c7 46 f6 01 00
-    jmp short 092e9h                          ; eb 05
+    jmp short 0932fh                          ; eb 05
     mov word [bp-00ah], strict word 00008h    ; c7 46 f6 08 00
     mov al, byte [bp-006h]                    ; 8a 46 fa
     and AL, strict byte 007h                  ; 24 07
     cmp AL, strict byte 001h                  ; 3c 01
-    jne short 09311h                          ; 75 1f
+    jne short 09357h                          ; 75 1f
     mov ax, bx                                ; 89 d8
     shr ax, 008h                              ; c1 e8 08
     test ax, ax                               ; 85 c0
-    jne short 09311h                          ; 75 16
+    jne short 09357h                          ; 75 16
     mov dx, strict word 0001ah                ; ba 1a 00
     mov ax, bx                                ; 89 d8
-    call 0927dh                               ; e8 7a ff
+    call 092c3h                               ; e8 7a ff
     mov dx, 00cfeh                            ; ba fe 0c
     in AL, DX                                 ; ec
     db  02ah, 0e4h
     ; sub ah, ah                                ; 2a e4
     cmp al, byte [bp-008h]                    ; 3a 46 f8
-    jbe short 09311h                          ; 76 03
+    jbe short 09357h                          ; 76 03
     mov byte [bp-008h], al                    ; 88 46 f8
     test di, di                               ; 85 ff
-    je short 0931ah                           ; 74 05
+    je short 09360h                           ; 74 05
     mov dx, strict word 00008h                ; ba 08 00
-    jmp short 0931ch                          ; eb 02
+    jmp short 09362h                          ; eb 02
     xor dx, dx                                ; 31 d2
     mov ax, bx                                ; 89 d8
-    call 0927dh                               ; e8 5c ff
+    call 092c3h                               ; e8 5c ff
     mov dx, 00cfch                            ; ba fc 0c
     in eax, DX                                ; 66 ed
     db  08bh, 0d0h
@@ -13756,49 +13788,46 @@ pci16_find_device_:                          ; 0xf92a1 LB 0xf7
     mov word [bp-00ch], dx                    ; 89 56 f4
     mov word [bp-010h], strict word 00000h    ; c7 46 f0 00 00
     test di, di                               ; 85 ff
-    je short 0934bh                           ; 74 0f
+    je short 09391h                           ; 74 0f
     mov cx, strict word 00008h                ; b9 08 00
     shr dx, 1                                 ; d1 ea
     rcr ax, 1                                 ; d1 d8
-    loop 0933fh                               ; e2 fa
+    loop 09385h                               ; e2 fa
     mov word [bp-00eh], ax                    ; 89 46 f2
     mov word [bp-00ch], dx                    ; 89 56 f4
     mov ax, word [bp-00ch]                    ; 8b 46 f4
     cmp ax, word [bp-014h]                    ; 3b 46 ec
-    jne short 0935bh                          ; 75 08
+    jne short 093a1h                          ; 75 08
     mov ax, word [bp-00eh]                    ; 8b 46 f2
     cmp ax, word [bp-012h]                    ; 3b 46 ee
-    je short 09361h                           ; 74 06
+    je short 093a7h                           ; 74 06
     cmp word [bp-010h], strict byte 00000h    ; 83 7e f0 00
-    je short 09367h                           ; 74 06
+    je short 093adh                           ; 74 06
     dec si                                    ; 4e
     cmp si, strict byte 0ffffh                ; 83 fe ff
-    je short 09379h                           ; 74 12
+    je short 093bfh                           ; 74 12
     add bx, word [bp-00ah]                    ; 03 5e f6
     mov dx, bx                                ; 89 da
     shr dx, 008h                              ; c1 ea 08
     movzx ax, byte [bp-008h]                  ; 0f b6 46 f8
     cmp dx, ax                                ; 39 c2
-    jbe near 092b7h                           ; 0f 86 3e ff
+    jbe near 092fdh                           ; 0f 86 3e ff
     cmp si, strict byte 0ffffh                ; 83 fe ff
-    jne short 09382h                          ; 75 04
+    jne short 093c8h                          ; 75 04
     mov ax, bx                                ; 89 d8
-    jmp short 09385h                          ; eb 03
+    jmp short 093cbh                          ; eb 03
     mov ax, strict word 0ffffh                ; b8 ff ff
     lea sp, [bp-004h]                         ; 8d 66 fc
     pop di                                    ; 5f
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-    jp short 09322h                           ; 7a 94
+    rcl byte [si-06b26h], 0edh                ; c0 94 da 94 ed
     xchg sp, ax                               ; 94
-    xchg sp, ax                               ; 94
-    cmpsw                                     ; a7
-    xchg sp, ax                               ; 94
-    mov sp, 0cf94h                            ; bc 94 cf
-    xchg sp, ax                               ; 94
-    loop 0932ch                               ; e2 94
-_pci16_function:                             ; 0xf9398 LB 0x1d7
+    add dl, byte [di-06aebh]                  ; 02 95 15 95
+    db  028h
+    xchg bp, ax                               ; 95
+_pci16_function:                             ; 0xf93de LB 0x1d7
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -13812,69 +13841,69 @@ _pci16_function:                             ; 0xf9398 LB 0x1d7
     mov ax, word [bp+020h]                    ; 8b 46 20
     xor ah, ah                                ; 30 e4
     cmp bx, strict byte 00003h                ; 83 fb 03
-    jc short 093d1h                           ; 72 1a
-    jbe short 09429h                          ; 76 70
+    jc short 09417h                           ; 72 1a
+    jbe short 0946fh                          ; 76 70
     cmp bx, strict byte 0000eh                ; 83 fb 0e
-    je near 094f6h                            ; 0f 84 36 01
+    je near 0953ch                            ; 0f 84 36 01
     cmp bx, strict byte 00008h                ; 83 fb 08
-    jc near 0953bh                            ; 0f 82 74 01
+    jc near 09581h                            ; 0f 82 74 01
     cmp bx, strict byte 0000dh                ; 83 fb 0d
-    jbe near 0944eh                           ; 0f 86 80 00
-    jmp near 0953bh                           ; e9 6a 01
+    jbe near 09494h                           ; 0f 86 80 00
+    jmp near 09581h                           ; e9 6a 01
     cmp bx, strict byte 00002h                ; 83 fb 02
-    je short 093f9h                           ; 74 23
+    je short 0943fh                           ; 74 23
     cmp bx, strict byte 00001h                ; 83 fb 01
-    jne near 0953bh                           ; 0f 85 5e 01
+    jne near 09581h                           ; 0f 85 5e 01
     mov word [bp+020h], strict word 00001h    ; c7 46 20 01 00
     mov word [bp+014h], 00210h                ; c7 46 14 10 02
     mov word [bp+01ch], strict word 00000h    ; c7 46 1c 00 00
     mov word [bp+018h], 04350h                ; c7 46 18 50 43
     mov word [bp+01ah], 02049h                ; c7 46 1a 49 20
-    jmp near 09568h                           ; e9 6f 01
+    jmp near 095aeh                           ; e9 6f 01
     cmp word [bp+018h], strict byte 0ffffh    ; 83 7e 18 ff
-    jne short 09405h                          ; 75 06
+    jne short 0944bh                          ; 75 06
     or ah, 083h                               ; 80 cc 83
-    jmp near 09561h                           ; e9 5c 01
+    jmp near 095a7h                           ; e9 5c 01
     mov bx, word [bp+008h]                    ; 8b 5e 08
     mov dx, word [bp+01ch]                    ; 8b 56 1c
     mov ax, word [bp+018h]                    ; 8b 46 18
     xor cx, cx                                ; 31 c9
-    call 092a1h                               ; e8 8e fe
+    call 092e7h                               ; e8 8e fe
     cmp ax, strict word 0ffffh                ; 3d ff ff
-    jne short 09423h                          ; 75 0b
+    jne short 09469h                          ; 75 0b
     mov ax, word [bp+020h]                    ; 8b 46 20
     xor ah, ah                                ; 30 e4
     or ah, 086h                               ; 80 cc 86
-    jmp near 09561h                           ; e9 3e 01
+    jmp near 095a7h                           ; e9 3e 01
     mov word [bp+014h], ax                    ; 89 46 14
-    jmp near 09568h                           ; e9 3f 01
+    jmp near 095aeh                           ; e9 3f 01
     mov bx, word [bp+008h]                    ; 8b 5e 08
     mov ax, word [bp+01ch]                    ; 8b 46 1c
     mov dx, word [bp+01eh]                    ; 8b 56 1e
     mov cx, strict word 00001h                ; b9 01 00
-    call 092a1h                               ; e8 69 fe
+    call 092e7h                               ; e8 69 fe
     cmp ax, strict word 0ffffh                ; 3d ff ff
-    jne short 09448h                          ; 75 0b
+    jne short 0948eh                          ; 75 0b
     mov ax, word [bp+020h]                    ; 8b 46 20
     xor ah, ah                                ; 30 e4
     or ah, 086h                               ; 80 cc 86
-    jmp near 09561h                           ; e9 19 01
+    jmp near 095a7h                           ; e9 19 01
     mov word [bp+014h], ax                    ; 89 46 14
-    jmp near 09568h                           ; e9 1a 01
+    jmp near 095aeh                           ; e9 1a 01
     cmp word [bp+004h], 00100h                ; 81 7e 04 00 01
-    jc short 0945bh                           ; 72 06
+    jc short 094a1h                           ; 72 06
     or ah, 087h                               ; 80 cc 87
-    jmp near 09561h                           ; e9 06 01
+    jmp near 095a7h                           ; e9 06 01
     mov dx, word [bp+004h]                    ; 8b 56 04
     mov ax, word [bp+014h]                    ; 8b 46 14
-    call 0927dh                               ; e8 19 fe
+    call 092c3h                               ; e8 19 fe
     mov bx, word [bp+020h]                    ; 8b 5e 20
     xor bh, bh                                ; 30 ff
     sub bx, strict byte 00008h                ; 83 eb 08
     cmp bx, strict byte 00005h                ; 83 fb 05
-    jnbe near 09568h                          ; 0f 87 f5 00
+    jnbe near 095aeh                          ; 0f 87 f5 00
     add bx, bx                                ; 01 db
-    jmp word [cs:bx-06c74h]                   ; 2e ff a7 8c 93
+    jmp word [cs:bx-06c2eh]                   ; 2e ff a7 d2 93
     mov bx, word [bp+01ch]                    ; 8b 5e 1c
     xor bl, bl                                ; 30 db
     mov dx, word [bp+004h]                    ; 8b 56 04
@@ -13885,14 +13914,14 @@ _pci16_function:                             ; 0xf9398 LB 0x1d7
     ; sub ah, ah                                ; 2a e4
     or bx, ax                                 ; 09 c3
     mov word [bp+01ch], bx                    ; 89 5e 1c
-    jmp near 09568h                           ; e9 d4 00
+    jmp near 095aeh                           ; e9 d4 00
     mov dx, word [bp+004h]                    ; 8b 56 04
     xor dh, dh                                ; 30 f6
     and dl, 002h                              ; 80 e2 02
     add dx, 00cfch                            ; 81 c2 fc 0c
     in ax, DX                                 ; ed
     mov word [bp+01ch], ax                    ; 89 46 1c
-    jmp near 09568h                           ; e9 c1 00
+    jmp near 095aeh                           ; e9 c1 00
     mov dx, 00cfch                            ; ba fc 0c
     in eax, DX                                ; 66 ed
     db  08bh, 0d0h
@@ -13901,21 +13930,21 @@ _pci16_function:                             ; 0xf9398 LB 0x1d7
     xchg dx, ax                               ; 92
     mov word [bp+01ch], ax                    ; 89 46 1c
     mov word [bp+01eh], dx                    ; 89 56 1e
-    jmp near 09568h                           ; e9 ac 00
+    jmp near 095aeh                           ; e9 ac 00
     mov ax, word [bp+01ch]                    ; 8b 46 1c
     mov dx, word [bp+004h]                    ; 8b 56 04
     xor dh, dh                                ; 30 f6
     and dl, 003h                              ; 80 e2 03
     add dx, 00cfch                            ; 81 c2 fc 0c
     out DX, AL                                ; ee
-    jmp near 09568h                           ; e9 99 00
+    jmp near 095aeh                           ; e9 99 00
     mov ax, word [bp+01ch]                    ; 8b 46 1c
     mov dx, word [bp+004h]                    ; 8b 56 04
     xor dh, dh                                ; 30 f6
     and dl, 002h                              ; 80 e2 02
     add dx, 00cfch                            ; 81 c2 fc 0c
     out DX, ax                                ; ef
-    jmp near 09568h                           ; e9 86 00
+    jmp near 095aeh                           ; e9 86 00
     mov ax, word [bp+01ch]                    ; 8b 46 1c
     mov cx, word [bp+01eh]                    ; 8b 4e 1e
     mov dx, 00cfch                            ; ba fc 0c
@@ -13924,20 +13953,20 @@ _pci16_function:                             ; 0xf9398 LB 0x1d7
     db  08bh, 0c1h
     ; mov ax, cx                                ; 8b c1
     out DX, eax                               ; 66 ef
-    jmp short 09568h                          ; eb 72
+    jmp short 095aeh                          ; eb 72
     mov bx, word [bp+004h]                    ; 8b 5e 04
     mov es, [bp+026h]                         ; 8e 46 26
     mov word [bp-008h], bx                    ; 89 5e f8
     mov [bp-006h], es                         ; 8c 46 fa
     mov cx, word [0f4a0h]                     ; 8b 0e a0 f4
     cmp cx, word [es:bx]                      ; 26 3b 0f
-    jbe short 0951ch                          ; 76 11
+    jbe short 09562h                          ; 76 11
     mov ax, word [bp+020h]                    ; 8b 46 20
     xor ah, ah                                ; 30 e4
     or ah, 089h                               ; 80 cc 89
     mov word [bp+020h], ax                    ; 89 46 20
     or word [bp+02ch], strict byte 00001h     ; 83 4e 2c 01
-    jmp short 09530h                          ; eb 14
+    jmp short 09576h                          ; eb 14
     les di, [es:bx+002h]                      ; 26 c4 7f 02
     mov si, 0f2c0h                            ; be c0 f2
     mov dx, ds                                ; 8c da
@@ -13949,18 +13978,18 @@ _pci16_function:                             ; 0xf9398 LB 0x1d7
     mov ax, word [0f4a0h]                     ; a1 a0 f4
     les bx, [bp-008h]                         ; c4 5e f8
     mov word [es:bx], ax                      ; 26 89 07
-    jmp short 09568h                          ; eb 2d
+    jmp short 095aeh                          ; eb 2d
     mov bx, 00da8h                            ; bb a8 0d
     mov cx, ds                                ; 8c d9
     mov ax, strict word 00004h                ; b8 04 00
-    call 01931h                               ; e8 eb 83
+    call 01931h                               ; e8 a5 83
     mov ax, word [bp+014h]                    ; 8b 46 14
     push ax                                   ; 50
     mov ax, word [bp+020h]                    ; 8b 46 20
     push ax                                   ; 50
     push 00d5eh                               ; 68 5e 0d
     push strict byte 00004h                   ; 6a 04
-    call 01972h                               ; e8 1c 84
+    call 01972h                               ; e8 d6 83
     add sp, strict byte 00008h                ; 83 c4 08
     mov ax, word [bp+020h]                    ; 8b 46 20
     xor ah, ah                                ; 30 e4
@@ -13972,7 +14001,7 @@ _pci16_function:                             ; 0xf9398 LB 0x1d7
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn                                      ; c3
-pci_find_classcode_:                         ; 0xf956f LB 0x2b
+pci_find_classcode_:                         ; 0xf95b5 LB 0x2b
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
@@ -13987,7 +14016,7 @@ pci_find_classcode_:                         ; 0xf956f LB 0x2b
     ; mov cx, dx                                ; 8b ca
     int 01ah                                  ; cd 1a
     cmp ah, 000h                              ; 80 fc 00
-    je near 09590h                            ; 0f 84 03 00
+    je near 095d6h                            ; 0f 84 03 00
     mov bx, strict word 0ffffh                ; bb ff ff
     mov ax, bx                                ; 89 d8
     lea sp, [bp-006h]                         ; 8d 66 fa
@@ -13996,7 +14025,7 @@ pci_find_classcode_:                         ; 0xf956f LB 0x2b
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-pci_read_config_byte_:                       ; 0xf959a LB 0x24
+pci_read_config_byte_:                       ; 0xf95e0 LB 0x24
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -14015,7 +14044,7 @@ pci_read_config_byte_:                       ; 0xf959a LB 0x24
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
-pci_read_config_word_:                       ; 0xf95be LB 0x22
+pci_read_config_word_:                       ; 0xf9604 LB 0x22
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -14034,7 +14063,7 @@ pci_read_config_word_:                       ; 0xf95be LB 0x22
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
-pci_read_config_dword_:                      ; 0xf95e0 LB 0x27
+pci_read_config_dword_:                      ; 0xf9626 LB 0x27
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push cx                                   ; 51
@@ -14055,7 +14084,7 @@ pci_read_config_dword_:                      ; 0xf95e0 LB 0x27
     pop cx                                    ; 59
     pop bp                                    ; 5d
     retn                                      ; c3
-vds_is_present_:                             ; 0xf9607 LB 0x1d
+vds_is_present_:                             ; 0xf964d LB 0x1d
     push bx                                   ; 53
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
@@ -14063,7 +14092,7 @@ vds_is_present_:                             ; 0xf9607 LB 0x1d
     mov ax, strict word 00040h                ; b8 40 00
     mov es, ax                                ; 8e c0
     test byte [es:bx], 020h                   ; 26 f6 07 20
-    je short 0961fh                           ; 74 06
+    je short 09665h                           ; 74 06
     mov ax, strict word 00001h                ; b8 01 00
     pop bp                                    ; 5d
     pop bx                                    ; 5b
@@ -14072,7 +14101,7 @@ vds_is_present_:                             ; 0xf9607 LB 0x1d
     pop bp                                    ; 5d
     pop bx                                    ; 5b
     retn                                      ; c3
-vds_real_to_lin_:                            ; 0xf9624 LB 0x1e
+vds_real_to_lin_:                            ; 0xf966a LB 0x1e
     push bx                                   ; 53
     push cx                                   ; 51
     push bp                                   ; 55
@@ -14083,7 +14112,7 @@ vds_real_to_lin_:                            ; 0xf9624 LB 0x1e
     mov cx, strict word 00004h                ; b9 04 00
     sal ax, 1                                 ; d1 e0
     rcl dx, 1                                 ; d1 d2
-    loop 09632h                               ; e2 fa
+    loop 09678h                               ; e2 fa
     xor cx, cx                                ; 31 c9
     add ax, bx                                ; 01 d8
     adc dx, cx                                ; 11 ca
@@ -14091,7 +14120,7 @@ vds_real_to_lin_:                            ; 0xf9624 LB 0x1e
     pop cx                                    ; 59
     pop bx                                    ; 5b
     retn                                      ; c3
-vds_build_sg_list_:                          ; 0xf9642 LB 0x79
+vds_build_sg_list_:                          ; 0xf9688 LB 0x79
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push si                                   ; 56
@@ -14105,23 +14134,23 @@ vds_build_sg_list_:                          ; 0xf9642 LB 0x79
     mov word [es:di], bx                      ; 26 89 1d
     mov bx, word [bp+006h]                    ; 8b 5e 06
     mov word [es:di+002h], bx                 ; 26 89 5d 02
-    call 09624h                               ; e8 c3 ff
+    call 0966ah                               ; e8 c3 ff
     mov es, si                                ; 8e c6
     mov word [es:di+004h], ax                 ; 26 89 45 04
     mov word [es:di+006h], dx                 ; 26 89 55 06
     mov word [es:di+008h], strict word 00000h ; 26 c7 45 08 00 00
-    call 09607h                               ; e8 93 ff
+    call 0964dh                               ; e8 93 ff
     test ax, ax                               ; 85 c0
-    je short 0968bh                           ; 74 13
+    je short 096d1h                           ; 74 13
     mov es, si                                ; 8e c6
     mov ax, 08105h                            ; b8 05 81
     mov dx, strict word 00000h                ; ba 00 00
     int 04bh                                  ; cd 4b
-    jc near 09688h                            ; 0f 82 02 00
+    jc near 096ceh                            ; 0f 82 02 00
     db  032h, 0c0h
     ; xor al, al                                ; 32 c0
     cbw                                       ; 98
-    jmp short 096b2h                          ; eb 27
+    jmp short 096f8h                          ; eb 27
     mov es, si                                ; 8e c6
     mov word [es:di+00eh], strict word 00001h ; 26 c7 45 0e 01 00
     mov dx, word [es:di+004h]                 ; 26 8b 55 04
@@ -14138,21 +14167,21 @@ vds_build_sg_list_:                          ; 0xf9642 LB 0x79
     pop si                                    ; 5e
     pop bp                                    ; 5d
     retn 00004h                               ; c2 04 00
-vds_free_sg_list_:                           ; 0xf96bb LB 0x35
+vds_free_sg_list_:                           ; 0xf9701 LB 0x3f
     push bp                                   ; 55
     mov bp, sp                                ; 89 e5
     push bx                                   ; 53
     push di                                   ; 57
     mov bx, ax                                ; 89 c3
-    call 09607h                               ; e8 42 ff
+    call 0964dh                               ; e8 42 ff
     test ax, ax                               ; 85 c0
-    je short 096dch                           ; 74 13
+    je short 09722h                           ; 74 13
     mov di, bx                                ; 89 df
     mov es, dx                                ; 8e c2
     mov ax, 08106h                            ; b8 06 81
     mov dx, strict word 00000h                ; ba 00 00
     int 04bh                                  ; cd 4b
-    jc near 096dbh                            ; 0f 82 02 00
+    jc near 09721h                            ; 0f 82 02 00
     db  032h, 0c0h
     ; xor al, al                                ; 32 c0
     cbw                                       ; 98
@@ -14163,8 +14192,8 @@ vds_free_sg_list_:                           ; 0xf96bb LB 0x35
     pop bx                                    ; 5b
     pop bp                                    ; 5d
     retn                                      ; c3
-    times 0x5 db 0
-__U4D:                                       ; 0xf96f0 LB 0x39
+    times 0xf db 0
+__U4D:                                       ; 0xf9740 LB 0x39
     pushfw                                    ; 9c
     push eax                                  ; 66 50
     push edx                                  ; 66 52
@@ -14194,7 +14223,7 @@ __U4D:                                       ; 0xf96f0 LB 0x39
     rol eax, 010h                             ; 66 c1 c0 10
     popfw                                     ; 9d
     retn                                      ; c3
-__U4M:                                       ; 0xf9729 LB 0x31
+__U4M:                                       ; 0xf9779 LB 0x31
     pushfw                                    ; 9c
     push eax                                  ; 66 50
     push edx                                  ; 66 52
@@ -14219,7 +14248,7 @@ __U4M:                                       ; 0xf9729 LB 0x31
     rol eax, 010h                             ; 66 c1 c0 10
     popfw                                     ; 9d
     retn                                      ; c3
-_fmemset_:                                   ; 0xf975a LB 0xd
+_fmemset_:                                   ; 0xf97aa LB 0xd
     push di                                   ; 57
     mov es, dx                                ; 8e c2
     db  08bh, 0f8h
@@ -14229,7 +14258,7 @@ _fmemset_:                                   ; 0xf975a LB 0xd
     xchg al, bl                               ; 86 d8
     pop di                                    ; 5f
     retn                                      ; c3
-_fmemcpy_:                                   ; 0xf9767 LB 0x33
+_fmemcpy_:                                   ; 0xf97b7 LB 0x33
     push bp                                   ; 55
     db  08bh, 0ech
     ; mov bp, sp                                ; 8b ec
@@ -14249,19 +14278,21 @@ _fmemcpy_:                                   ; 0xf9767 LB 0x33
     pop di                                    ; 5f
     leave                                     ; c9
     retn                                      ; c3
-    add byte [bx+si-04d69h], dh               ; 00 b0 97 b2
-    xchg di, ax                               ; 97
-    mov DH, strict byte 097h                  ; b6 97
-    mov DH, strict byte 097h                  ; b6 97
-    mov DH, strict byte 097h                  ; b6 97
-    mov ax, 0b897h                            ; b8 97 b8
-    xchg di, ax                               ; 97
-    mov dx, 0be97h                            ; ba 97 be
-    xchg di, ax                               ; 97
-    mov si, 0c097h                            ; be 97 c0
-    xchg di, ax                               ; 97
-    lds dx, [bx-06839h]                       ; c5 97 c7 97
-apm_worker:                                  ; 0xf979a LB 0x3a
+    add byte [bx+si], al                      ; 00 00
+    cbw                                       ; 98
+    add bl, byte [bx+si-067fah]               ; 02 98 06 98
+    push ES                                   ; 06
+    cbw                                       ; 98
+    push ES                                   ; 06
+    cbw                                       ; 98
+    or byte [bx+si-067f8h], bl                ; 08 98 08 98
+    or bl, byte [bx+si-067f2h]                ; 0a 98 0e 98
+    push CS                                   ; 0e
+    cbw                                       ; 98
+    adc byte [bx+si-067ebh], bl               ; 10 98 15 98
+    pop SS                                    ; 17
+    cbw                                       ; 98
+apm_worker:                                  ; 0xf97ea LB 0x3a
     sti                                       ; fb
     push ax                                   ; 50
     db  032h, 0e4h
@@ -14273,29 +14304,29 @@ apm_worker:                                  ; 0xf979a LB 0x3a
     cmp AL, strict byte 00dh                  ; 3c 0d
     pop ax                                    ; 58
     mov AH, strict byte 053h                  ; b4 53
-    jnc short 097d0h                          ; 73 25
-    jmp word [cs:bp-06880h]                   ; 2e ff a6 80 97
-    jmp short 097ceh                          ; eb 1c
+    jnc short 09820h                          ; 73 25
+    jmp word [cs:bp-06830h]                   ; 2e ff a6 d0 97
+    jmp short 0981eh                          ; eb 1c
     sti                                       ; fb
     hlt                                       ; f4
-    jmp short 097ceh                          ; eb 18
-    jmp short 097ceh                          ; eb 16
-    jmp short 097d0h                          ; eb 16
+    jmp short 0981eh                          ; eb 18
+    jmp short 0981eh                          ; eb 16
+    jmp short 09820h                          ; eb 16
     mov AH, strict byte 080h                  ; b4 80
-    jmp short 097d2h                          ; eb 14
-    jmp short 097d0h                          ; eb 10
+    jmp short 09822h                          ; eb 14
+    jmp short 09820h                          ; eb 10
     mov ax, 00102h                            ; b8 02 01
-    jmp short 097ceh                          ; eb 09
-    jmp short 097ceh                          ; eb 07
+    jmp short 0981eh                          ; eb 09
+    jmp short 0981eh                          ; eb 07
     mov BL, strict byte 000h                  ; b3 00
     mov cx, strict word 00000h                ; b9 00 00
-    jmp short 097ceh                          ; eb 00
+    jmp short 0981eh                          ; eb 00
     clc                                       ; f8
     retn                                      ; c3
     mov AH, strict byte 009h                  ; b4 09
     stc                                       ; f9
     retn                                      ; c3
-apm_pm16_entry:                              ; 0xf97d4 LB 0x11
+apm_pm16_entry:                              ; 0xf9824 LB 0x11
     mov AH, strict byte 002h                  ; b4 02
     push DS                                   ; 1e
     push bp                                   ; 55
@@ -14303,13 +14334,13 @@ apm_pm16_entry:                              ; 0xf97d4 LB 0x11
     pop bp                                    ; 5d
     add bp, strict byte 00008h                ; 83 c5 08
     mov ds, bp                                ; 8e dd
-    call 0979ah                               ; e8 b8 ff
+    call 097eah                               ; e8 b8 ff
     pop bp                                    ; 5d
     pop DS                                    ; 1f
     retf                                      ; cb
 
-  ; Padding 0x421b bytes at 0xf97e5
-  times 16923 db 0
+  ; Padding 0x41cb bytes at 0xf9835
+  times 16843 db 0
 
 section BIOS32 progbits vstart=0xda00 align=1 ; size=0x3cb class=CODE group=AUTO
 bios32_service:                              ; 0xfda00 LB 0x26
@@ -14356,7 +14387,7 @@ apm_pm32_entry:                              ; 0xfda40 LB 0x21
     pop bp                                    ; 5d
     add bp, strict byte 00008h                ; 83 c5 08
     push ebp                                  ; 66 55
-    mov bp, 097d6h                            ; bd d6 97
+    mov bp, 09826h                            ; bd 26 98
     add byte [bx+si], al                      ; 00 00
     push ebp                                  ; 66 55
     mov AH, strict byte 003h                  ; b4 03
@@ -15078,8 +15109,8 @@ hard_drive_post:                             ; 0xfe2d2 LB 0x12c
     cld                                       ; fc
     call 01badh                               ; e8 71 38
     call 01fa7h                               ; e8 68 3c
-    call 09051h                               ; e8 0f ad
-    call 080a8h                               ; e8 63 9d
+    call 09097h                               ; e8 55 ad
+    call 080d3h                               ; e8 8e 9d
     call 0ed2fh                               ; e8 e7 09
     call 0e2d2h                               ; e8 87 ff
     push CS                                   ; 0e
@@ -16079,7 +16110,7 @@ int15_handler:                               ; 0xff859 LB 0x2e
     pop DS                                    ; 1f
     popfw                                     ; 9d
     jmp short 0f895h                          ; eb 13
-    call 09188h                               ; e8 03 99
+    call 091ceh                               ; e8 49 99
     jmp short 0f87ch                          ; eb f5
 int15_handler_mouse:                         ; 0xff887 LB 0x5
     call 06f88h                               ; e8 fe 76
@@ -16208,7 +16239,7 @@ font8x8:                                     ; 0xffa6e LB 0x421
     db  000h, 000h, 0fch, 098h, 030h, 064h, 0fch, 000h, 01ch, 030h, 030h, 0e0h, 030h, 030h, 01ch, 000h
     db  018h, 018h, 018h, 000h, 018h, 018h, 018h, 000h, 0e0h, 030h, 030h, 01ch, 030h, 030h, 0e0h, 000h
     db  076h, 0dch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 010h, 038h, 06ch, 0c6h, 0c6h, 0feh, 000h
-    db  080h, 0fch, 0b1h, 075h, 00fh, 006h, 01eh, 00eh, 01fh, 0fch, 066h, 060h, 0e8h, 01bh, 095h, 066h
+    db  080h, 0fch, 0b1h, 075h, 00fh, 006h, 01eh, 00eh, 01fh, 0fch, 066h, 060h, 0e8h, 061h, 095h, 066h
     db  061h, 01fh, 007h, 0cfh, 006h, 01eh, 060h, 00eh, 01fh, 0fch, 0e8h, 0cah, 06dh, 061h, 01fh, 007h
     db  0cfh
 int70_handler:                               ; 0xffe8f LB 0x16
@@ -16317,4 +16348,4 @@ dummy_iret:                                  ; 0xfff53 LB 0x9d
     db  'XM'
 cpu_reset:                                   ; 0xffff0 LB 0x10
     jmp far 0f000h:0e05bh                     ; ea 5b e0 00 f0
-    db  030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 05dh
+    db  030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 03eh
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
index f29bd69..11364c2 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
@@ -1 +1 @@
-52f20c4019f05d0a8b5d96985ecebb03 *VBoxPcBios.rom
+dada536c6edc89409a8ebf3822aedeb9 *VBoxPcBios.rom
diff --git a/src/VBox/Devices/PC/BIOS/ahci.c b/src/VBox/Devices/PC/BIOS/ahci.c
index cb1ccf4..b0af223 100644
--- a/src/VBox/Devices/PC/BIOS/ahci.c
+++ b/src/VBox/Devices/PC/BIOS/ahci.c
@@ -45,6 +45,30 @@ typedef struct
 } ahci_prdt;
 
 /**
+ * SATA D2H FIS (Device to Host Frame Information Structure).
+ */
+typedef struct {
+    uint8_t     fis_type;   /* 34h */
+    uint8_t     intr;       /* Bit 6 indicates interrupt status. */
+    uint8_t     status;     /* Status register. */
+    uint8_t     error;      /* Error register. */
+    uint8_t     sec_no;     /* Sector number register. */
+    uint8_t     cyl_lo;     /* Cylinder low register. */
+    uint8_t     cyl_hi;     /* Cylinder high register. */
+    uint8_t     dev_hd;     /* Device/head register. */
+    uint8_t     sec_no_exp; /* Expanded sector number register. */
+    uint8_t     cyl_lo_exp; /* Expanded cylinder low register. */
+    uint8_t     cyl_hi_exp; /* Expanded cylinder high register. */
+    uint8_t     resvd0;
+    uint8_t     sec_cn;     /* Sector count register. */
+    uint8_t     sec_cn_exp; /* Expanded sector count register. */
+    uint16_t    resvd1;
+    uint32_t    resvd2;
+} fis_d2h;
+
+ct_assert(sizeof(fis_d2h) == 20);
+
+/**
  * AHCI controller data.
  */
 typedef struct
@@ -304,8 +328,7 @@ static void ahci_port_cmd_sync(ahci_t __far *ahci, uint8_t val)
         /* Disable command engine. */
         ahci_ctrl_clear_bits(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_CMD),
                              AHCI_REG_PORT_CMD_ST);
-
-        /** @todo: Examine status. */
+        /* Caller must examine status. */
     }
     else
         DBG_AHCI("AHCI: Invalid port given\n");
@@ -314,12 +337,13 @@ static void ahci_port_cmd_sync(ahci_t __far *ahci, uint8_t val)
 /**
  * Issue command to device.
  */
-static void ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd)
+static uint16_t ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd)
 {
     ahci_t __far    *ahci  = bios_dsk->ahci_seg :> 0;
     uint16_t        n_sect = bios_dsk->drqp.nsect;
     uint16_t        sectsz = bios_dsk->drqp.sect_sz;
     uint16_t        prdt_idx;
+    fis_d2h __far   *d2h;
 
     _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd));
 
@@ -383,8 +407,13 @@ static void ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd)
 
     ahci_port_cmd_sync(ahci, cmd);
 
+    /* Examine operation status. */
+    d2h = (void __far *)&ahci->abFisRecv[0x40];
+    DBG_AHCI("AHCI: ERR=%02x, STAT=%02x, SCNT=%02x\n", d2h->error, d2h->status, d2h->sec_cn);
+
     /* Unlock the buffer again. */
     vds_free_sg_list(&ahci->edds);
+    return d2h->error ? 4 : 0;
 }
 
 /**
@@ -489,6 +518,7 @@ static void ahci_port_init(ahci_t __far *ahci, uint8_t u8Port)
 int ahci_read_sectors(bio_dsk_t __far *bios_dsk)
 {
     uint16_t        device_id;
+    uint16_t        rc;
 
     device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
     if (device_id > BX_MAX_AHCI_DEVICES)
@@ -500,14 +530,14 @@ int ahci_read_sectors(bio_dsk_t __far *bios_dsk)
 
     high_bits_save(bios_dsk->ahci_seg :> 0);
     ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
-    ahci_cmd_data(bios_dsk, AHCI_CMD_READ_DMA_EXT);
+    rc = ahci_cmd_data(bios_dsk, AHCI_CMD_READ_DMA_EXT);
     DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
     bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect;
 #ifdef DMA_WORKAROUND
     rep_movsw(bios_dsk->drqp.buffer, bios_dsk->drqp.buffer, bios_dsk->drqp.nsect * 512 / 2);
 #endif
     high_bits_restore(bios_dsk->ahci_seg :> 0);
-    return 0;   //@todo!!
+    return rc;
 }
 
 /**
@@ -520,6 +550,7 @@ int ahci_read_sectors(bio_dsk_t __far *bios_dsk)
 int ahci_write_sectors(bio_dsk_t __far *bios_dsk)
 {
     uint16_t        device_id;
+    uint16_t        rc;
 
     device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
     if (device_id > BX_MAX_AHCI_DEVICES)
@@ -531,11 +562,11 @@ int ahci_write_sectors(bio_dsk_t __far *bios_dsk)
 
     high_bits_save(bios_dsk->ahci_seg :> 0);
     ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
-    ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT);
+    rc = ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT);
     DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
     bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect;
     high_bits_restore(bios_dsk->ahci_seg :> 0);
-    return 0;   //@todo!!
+    return rc;
 }
 
 //@todo: move
@@ -604,7 +635,6 @@ uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf,
     high_bits_restore(ahci);
 
     return ahci->aCmdHdr[1] == 0 ? 4 : 0;
-//    return 0;   //@todo!!
 }
 
 void ahci_port_detect_device(ahci_t __far *ahci, uint8_t u8Port)
diff --git a/src/VBox/Devices/PC/BIOS/scsi.c b/src/VBox/Devices/PC/BIOS/scsi.c
index 152d3ea..44aea7e 100644
--- a/src/VBox/Devices/PC/BIOS/scsi.c
+++ b/src/VBox/Devices/PC/BIOS/scsi.c
@@ -108,6 +108,15 @@ int scsi_cmd_data_in(uint16_t io_base, uint8_t target_id, uint8_t __far *aCDB,
         status = inb(io_base + VBSCSI_REGISTER_STATUS);
     while (status & VBSCSI_BUSY);
 
+    /* If any error occurred, inform the caller and don't bother reading the data. */
+    if (status & VBSCSI_ERROR) {
+        outb(io_base + VBSCSI_REGISTER_RESET, 0);
+
+        status = inb(io_base + VBSCSI_REGISTER_DEVSTAT);
+        DBG_SCSI("%s: read failed, device status %02X\n", __func__, status);
+        return 4;   /* Sector not found */
+    }
+
     /* Read in the data. The transfer length may be exactly 64K or more,
      * which needs a bit of care when we're using 16-bit 'rep ins'.
      */
@@ -163,6 +172,15 @@ int scsi_cmd_data_out(uint16_t io_base, uint8_t target_id, uint8_t __far *aCDB,
         status = inb(io_base + VBSCSI_REGISTER_STATUS);
     while (status & VBSCSI_BUSY);
 
+    /* If any error occurred, inform the caller. */
+    if (status & VBSCSI_ERROR) {
+        outb(io_base + VBSCSI_REGISTER_RESET, 0);
+
+        status = inb(io_base + VBSCSI_REGISTER_DEVSTAT);
+        DBG_SCSI("%s: write failed, device status %02X\n", __func__, status);
+        return 4;   /* Sector not found */
+    }
+
     return 0;
 }
 
@@ -398,6 +416,8 @@ void scsi_enumerate_attached_devices(uint16_t io_base)
         if (rc != 0)
             BX_PANIC("%s: SCSI_INQUIRY failed\n", __func__);
 
+        devcount_scsi = bios_dsk->scsi_devcount;
+
         /* Check the attached device. */
         if (   ((buffer[0] & 0xe0) == 0)
             && ((buffer[0] & 0x1f) == 0x00))
@@ -405,7 +425,7 @@ void scsi_enumerate_attached_devices(uint16_t io_base)
             DBG_SCSI("%s: Disk detected at %d\n", __func__, i);
 
             /* We add the disk only if the maximum is not reached yet. */
-            if (bios_dsk->scsi_devcount < BX_MAX_SCSI_DEVICES)
+            if (devcount_scsi < BX_MAX_SCSI_DEVICES)
             {
                 uint32_t    sectors, sector_size, cylinders;
                 uint16_t    heads, sectors_per_track;
@@ -426,6 +446,7 @@ void scsi_enumerate_attached_devices(uint16_t io_base)
                           | ((uint32_t)buffer[1] << 16)
                           | ((uint32_t)buffer[2] << 8)
                           | ((uint32_t)buffer[3]);
+                ++sectors;  /* Returned value is the last LBA, zero-based. */
 
                 sector_size =   ((uint32_t)buffer[4] << 24)
                               | ((uint32_t)buffer[5] << 16)
@@ -440,8 +461,6 @@ void scsi_enumerate_attached_devices(uint16_t io_base)
                     continue;
                 }
 
-                devcount_scsi = bios_dsk->scsi_devcount;
-
                 /* Get logical CHS geometry. */
                 switch (devcount_scsi)
                 {
@@ -536,7 +555,6 @@ void scsi_enumerate_attached_devices(uint16_t io_base)
                 write_byte(0x40, 0x75, hdcount);
 
                 devcount_scsi++;
-                bios_dsk->scsi_devcount = devcount_scsi;
             }
             else
             {
@@ -571,10 +589,11 @@ void scsi_enumerate_attached_devices(uint16_t io_base)
             bios_dsk->cdcount = cdcount;
 
             devcount_scsi++;
-            bios_dsk->scsi_devcount = devcount_scsi;
         }
         else
             DBG_SCSI("%s: No supported device detected at %d\n", __func__, i);
+
+        bios_dsk->scsi_devcount = devcount_scsi;
     }
 }
 
diff --git a/src/VBox/Devices/PC/DevPcBios.cpp b/src/VBox/Devices/PC/DevPcBios.cpp
index 1a58e4b..561f416 100644
--- a/src/VBox/Devices/PC/DevPcBios.cpp
+++ b/src/VBox/Devices/PC/DevPcBios.cpp
@@ -267,7 +267,7 @@ static DECLCALLBACK(int) pcbiosIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTI
             if (pThis->iShutdown == 8)
             {
                 pThis->iShutdown = 0;
-                LogRel(("DevPcBios: 8900h shutdown request.\n"));
+                LogRel(("DevPcBios: 8900h shutdown request\n"));
                 return PDMDevHlpVMPowerOff(pDevIns);
             }
         }
@@ -1106,7 +1106,7 @@ static DECLCALLBACK(int)  pcbiosConstruct(PPDMDEVINS pDevIns, int iInstance, PCF
                                 N_("Configuration error: Querying \"McfgLength\" as integer failed"));
 
 
-    LogRel(("[SMP] BIOS with %u CPUs\n", pThis->cCpus));
+    LogRel(("DevPcBios: [SMP] BIOS with %u CPUs\n", pThis->cCpus));
 
     rc = CFGMR3QueryU8Def(pCfg, "IOAPIC", &pThis->u8IOAPIC, 1);
     if (RT_FAILURE (rc))
@@ -1399,7 +1399,7 @@ static DECLCALLBACK(int)  pcbiosConstruct(PPDMDEVINS pDevIns, int iInstance, PCF
     {
         FwCommonPlantMpsTable(pDevIns, pThis->au8DMIPage + VBOX_DMI_TABLE_SIZE,
                               _4K - VBOX_DMI_TABLE_SIZE, pThis->cCpus);
-        LogRel(("MPS table at %08x\n", VBOX_DMI_TABLE_BASE + VBOX_DMI_TABLE_SIZE));
+        LogRel(("DevPcBios: MPS table at %08x\n", VBOX_DMI_TABLE_BASE + VBOX_DMI_TABLE_SIZE));
     }
 
     rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, _4K, pThis->au8DMIPage, _4K,
diff --git a/src/VBox/Devices/PC/ipxe/src/arch/i386/prefix/romprefix.S b/src/VBox/Devices/PC/ipxe/src/arch/i386/prefix/romprefix.S
index d3fd411..dd1dc67 100644
--- a/src/VBox/Devices/PC/ipxe/src/arch/i386/prefix/romprefix.S
+++ b/src/VBox/Devices/PC/ipxe/src/arch/i386/prefix/romprefix.S
@@ -418,8 +418,12 @@ no_pmm:
 	movl	$0xa0000, %ebp	/* Inhibit relocation during POST */
 	pushw	%cs
 	call	exec
-#endif
 2:
+#else
+	xorw	%di, %di
+	movw	$init_message_done, %si
+	call	print_message
+#endif
 	/* Restore registers */
 	popw	%gs
 	popw	%fs
diff --git a/src/VBox/Devices/Serial/DrvTCP.cpp b/src/VBox/Devices/Serial/DrvTCP.cpp
new file mode 100644
index 0000000..ac7a254
--- /dev/null
+++ b/src/VBox/Devices/Serial/DrvTCP.cpp
@@ -0,0 +1,492 @@
+/* $Id: DrvTCP.cpp $ */
+/** @file
+ * TCP socket driver implementing the IStream interface.
+ */
+
+/*
+ * Copyright (C) 2006-2015 Oracle Corporation.
+ *
+ * This file was contributed by Alexey Eromenko (derived from DrvNamedPipe)
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_DRV_TCP
+#include <VBox/vmm/pdmdrv.h>
+#include <iprt/assert.h>
+#include <iprt/file.h>
+#include <iprt/stream.h>
+#include <iprt/alloc.h>
+#include <iprt/string.h>
+#include <iprt/semaphore.h>
+#include <iprt/uuid.h>
+#include <stdlib.h>
+
+#include "VBoxDD.h"
+
+#ifdef RT_OS_WINDOWS
+# include <ws2tcpip.h>
+#else /* !RT_OS_WINDOWS */
+# include <errno.h>
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <netdb.h>
+# ifndef SHUT_RDWR /* OS/2 */
+#  define SHUT_RDWR 3
+# endif
+#endif /* !RT_OS_WINDOWS */
+
+#ifndef SHUT_RDWR
+# ifdef SD_BOTH
+#  define SHUT_RDWR SD_BOTH
+# else
+#  define SHUT_RDWR 2
+# endif
+#endif
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+/** Converts a pointer to DRVTCP::IMedia to a PDRVTCP. */
+#define PDMISTREAM_2_DRVTCP(pInterface) ( (PDRVTCP)((uintptr_t)pInterface - RT_OFFSETOF(DRVTCP, IStream)) )
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * TCP driver instance data.
+ *
+ * @implements PDMISTREAM
+ */
+typedef struct DRVTCP
+{
+    /** The stream interface. */
+    PDMISTREAM          IStream;
+    /** Pointer to the driver instance. */
+    PPDMDRVINS          pDrvIns;
+    /** Pointer to the TCP server address:port or port only. (Freed by MM) */
+    char                *pszLocation;
+    /** Flag whether VirtualBox represents the server or client side. */
+    bool                fIsServer;
+
+    /** Socket handle of the TCP socket for server. */
+    int                 TCPServer;
+    /** Socket handle of the TCP socket connection. */
+    int                 TCPConnection;
+
+    /** Thread for listening for new connections. */
+    RTTHREAD            ListenThread;
+    /** Flag to signal listening thread to shut down. */
+    bool volatile       fShutdown;
+} DRVTCP, *PDRVTCP;
+
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+
+
+/** @copydoc PDMISTREAM::pfnRead */
+static DECLCALLBACK(int) drvTCPRead(PPDMISTREAM pInterface, void *pvBuf, size_t *pcbRead)
+{
+    int rc = VINF_SUCCESS;
+    PDRVTCP pThis = PDMISTREAM_2_DRVTCP(pInterface);
+    LogFlow(("%s: pvBuf=%p *pcbRead=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbRead, pThis->pszLocation));
+
+    Assert(pvBuf);
+
+    if (pThis->TCPConnection != -1)
+    {
+        ssize_t cbReallyRead;
+        unsigned cbBuf = (unsigned)*pcbRead;
+        cbReallyRead = recv(pThis->TCPConnection, (char *)pvBuf, cbBuf, 0);
+        if (cbReallyRead == 0)
+        {
+            int tmp = pThis->TCPConnection;
+            pThis->TCPConnection = -1;
+#ifdef RT_OS_WINDOWS
+            closesocket(tmp);
+#else
+            close(tmp);
+#endif
+        }
+        else if (cbReallyRead == -1)
+        {
+            cbReallyRead = 0;
+            rc = RTErrConvertFromErrno(errno);
+        }
+        *pcbRead = cbReallyRead;
+    }
+    else
+    {
+        RTThreadSleep(100);
+        *pcbRead = 0;
+    }
+
+    LogFlow(("%s: *pcbRead=%zu returns %Rrc\n", __FUNCTION__, *pcbRead, rc));
+    return rc;
+}
+
+
+/** @copydoc PDMISTREAM::pfnWrite */
+static DECLCALLBACK(int) drvTCPWrite(PPDMISTREAM pInterface, const void *pvBuf, size_t *pcbWrite)
+{
+    int rc = VINF_SUCCESS;
+    PDRVTCP pThis = PDMISTREAM_2_DRVTCP(pInterface);
+    LogFlow(("%s: pvBuf=%p *pcbWrite=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbWrite, pThis->pszLocation));
+
+    Assert(pvBuf);
+    if (pThis->TCPConnection != -1)
+    {
+        ssize_t cbWritten;
+        unsigned cbBuf = (unsigned)*pcbWrite;
+        cbWritten = send(pThis->TCPConnection, (const char *)pvBuf, cbBuf, 0);
+        if (cbWritten == 0)
+        {
+            int tmp = pThis->TCPConnection;
+            pThis->TCPConnection = -1;
+#ifdef RT_OS_WINDOWS
+            closesocket(tmp);
+#else
+            close(tmp);
+#endif
+        }
+        else if (cbWritten == -1)
+        {
+            cbWritten = 0;
+            rc = RTErrConvertFromErrno(errno);
+        }
+        *pcbWrite = cbWritten;
+    }
+
+    LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+static DECLCALLBACK(void *) drvTCPQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+    PPDMDRVINS      pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
+    PDRVTCP         pThis   = PDMINS_2_DATA(pDrvIns, PDRVTCP);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMISTREAM, &pThis->IStream);
+    return NULL;
+}
+
+
+/* -=-=-=-=- listen thread -=-=-=-=- */
+
+/**
+ * Receive thread loop.
+ *
+ * @returns 0 on success.
+ * @param   ThreadSelf  Thread handle to this thread.
+ * @param   pvUser      User argument.
+ */
+static DECLCALLBACK(int) drvTCPListenLoop(RTTHREAD ThreadSelf, void *pvUser)
+{
+    PDRVTCP pThis = (PDRVTCP)pvUser;
+    int     rc = VINF_SUCCESS;
+
+    while (RT_LIKELY(!pThis->fShutdown))
+    {
+        if (listen(pThis->TCPServer, 0) == -1)
+        {
+            rc = RTErrConvertFromErrno(errno);
+            LogRel(("DrvTCP%d: listen failed, rc=%Rrc\n", pThis->pDrvIns->iInstance, rc));
+            break;
+        }
+        int s = accept(pThis->TCPServer, NULL, NULL);
+        if (s == -1)
+        {
+            rc = RTErrConvertFromErrno(errno);
+            LogRel(("DrvTCP%d: accept failed, rc=%Rrc\n", pThis->pDrvIns->iInstance, rc));
+            break;
+        }
+        if (pThis->TCPConnection != -1)
+        {
+            LogRel(("DrvTCP%d: only single connection supported\n", pThis->pDrvIns->iInstance));
+#ifdef RT_OS_WINDOWS
+            closesocket(s);
+#else
+            close(s);
+#endif
+        }
+        else
+            pThis->TCPConnection = s;
+    }
+
+    return VINF_SUCCESS;
+}
+
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
+
+/**
+ * Common worker for drvTCPPowerOff and drvTCPDestructor.
+ *
+ * @param   pThis               The instance data.
+ */
+static void drvTCPShutdownListener(PDRVTCP pThis)
+{
+    /*
+     * Signal shutdown of the listener thread.
+     */
+    pThis->fShutdown = true;
+    if (    pThis->fIsServer
+        &&  pThis->TCPServer != -1)
+    {
+        int rc = shutdown(pThis->TCPServer, SHUT_RDWR);
+        AssertRC(rc == 0); NOREF(rc);
+
+#ifdef RT_OS_WINDOWS
+        rc = closesocket(pThis->TCPServer);
+#else
+        rc = close(pThis->TCPServer);
+#endif
+        AssertRC(rc == 0);
+        pThis->TCPServer = -1;
+    }
+}
+
+
+/**
+ * Power off a TCP socket stream driver instance.
+ *
+ * This does most of the destruction work, to avoid ordering dependencies.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvTCPPowerOff(PPDMDRVINS pDrvIns)
+{
+    PDRVTCP pThis = PDMINS_2_DATA(pDrvIns, PDRVTCP);
+    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
+
+    drvTCPShutdownListener(pThis);
+}
+
+
+/**
+ * Destruct a TCP socket stream driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that
+ * any non-VM resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvTCPDestruct(PPDMDRVINS pDrvIns)
+{
+    PDRVTCP pThis = PDMINS_2_DATA(pDrvIns, PDRVTCP);
+    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    drvTCPShutdownListener(pThis);
+
+    /*
+     * While the thread exits, clean up as much as we can.
+     */
+
+    Assert(pThis->TCPServer == -1);
+    if (pThis->TCPConnection != -1)
+    {
+        int rc = shutdown(pThis->TCPConnection, SHUT_RDWR);
+        AssertRC(rc == 0); NOREF(rc);
+
+#ifdef RT_OS_WINDOWS
+        rc = closesocket(pThis->TCPConnection);
+#else
+        rc = close(pThis->TCPConnection);
+#endif
+        Assert(rc == 0);
+        pThis->TCPConnection = -1;
+    }
+    if (   pThis->fIsServer
+        && pThis->pszLocation)
+        RTFileDelete(pThis->pszLocation);
+
+
+    MMR3HeapFree(pThis->pszLocation);
+    pThis->pszLocation = NULL;
+
+    /*
+     * Wait for the thread.
+     */
+    if (pThis->ListenThread != NIL_RTTHREAD)
+    {
+        int rc = RTThreadWait(pThis->ListenThread, 30000, NULL);
+        if (RT_SUCCESS(rc))
+            pThis->ListenThread = NIL_RTTHREAD;
+        else
+            LogRel(("DrvTCP%d: listen thread did not terminate (%Rrc)\n", pDrvIns->iInstance, rc));
+    }
+
+}
+
+
+/**
+ * Construct a TCP socket stream driver instance.
+ *
+ * @copydoc FNPDMDRVCONSTRUCT
+ */
+static DECLCALLBACK(int) drvTCPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
+{
+    PDRVTCP pThis = PDMINS_2_DATA(pDrvIns, PDRVTCP);
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
+
+    /*
+     * Init the static parts.
+     */
+    pThis->pDrvIns                      = pDrvIns;
+    pThis->pszLocation                  = NULL;
+    pThis->fIsServer                    = false;
+
+    pThis->TCPServer                    = -1;
+    pThis->TCPConnection                = -1;
+
+    pThis->ListenThread                 = NIL_RTTHREAD;
+    pThis->fShutdown                    = false;
+    /* IBase */
+    pDrvIns->IBase.pfnQueryInterface    = drvTCPQueryInterface;
+    /* IStream */
+    pThis->IStream.pfnRead              = drvTCPRead;
+    pThis->IStream.pfnWrite             = drvTCPWrite;
+
+    /*
+     * Validate and read the configuration.
+     */
+    PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "Location|IsServer", "");
+
+    int rc = CFGMR3QueryStringAlloc(pCfg, "Location", &pThis->pszLocation);
+    if (RT_FAILURE(rc))
+        return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
+                                   N_("Configuration error: querying \"Location\" resulted in %Rrc"), rc);
+    rc = CFGMR3QueryBool(pCfg, "IsServer", &pThis->fIsServer);
+    if (RT_FAILURE(rc))
+        return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
+                                   N_("Configuration error: querying \"IsServer\" resulted in %Rrc"), rc);
+
+    /*
+     * Create/Open the socket.
+     */
+    int s = socket(PF_INET, SOCK_STREAM, 0);
+    if (s == -1)
+        return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS,
+                                   N_("DrvTCP#%d failed to create socket"), pDrvIns->iInstance);
+
+    struct sockaddr_in addr;
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = AF_INET;
+
+    if (pThis->fIsServer)
+    {
+        addr.sin_addr.s_addr = INADDR_ANY;
+        addr.sin_port = htons(/*PORT*/ atoi(pThis->pszLocation));
+
+        /* Bind address to the telnet socket. */
+        pThis->TCPServer = s;
+        RTFileDelete(pThis->pszLocation);
+        if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
+            return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS,
+                                       N_("DrvTCP#%d failed to bind to socket %s"),
+                                       pDrvIns->iInstance, pThis->pszLocation);
+        rc = RTThreadCreate(&pThis->ListenThread, drvTCPListenLoop, (void *)pThis, 0,
+                            RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "DrvTCPStream");
+        if (RT_FAILURE(rc))
+            return PDMDrvHlpVMSetError(pDrvIns, rc,  RT_SRC_POS,
+                                       N_("DrvTCP#%d failed to create listening thread"), pDrvIns->iInstance);
+    }
+    else
+    {
+        char *token;
+        const char *delim = ":";
+        struct hostent *server;
+        token = strtok(pThis->pszLocation, delim);
+        if(token) {
+            server = gethostbyname(token);
+            memmove((char *)&addr.sin_addr.s_addr,
+                    (char *)server->h_addr,
+                     server->h_length);
+        }
+        token = strtok(NULL, delim);
+        if(token) {
+            addr.sin_port = htons(/*PORT*/ atoi(token));
+        }
+
+        /* Connect to the telnet socket. */
+        pThis->TCPConnection = s;
+        if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
+            return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS,
+                                       N_("DrvTCP#%d failed to connect to socket %s"),
+                                       pDrvIns->iInstance, pThis->pszLocation);
+    }
+
+    LogRel(("DrvTCP: %s, %s\n", pThis->pszLocation, pThis->fIsServer ? "server" : "client"));
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * TCP stream driver registration record.
+ */
+const PDMDRVREG g_DrvTCP =
+{
+    /* u32Version */
+    PDM_DRVREG_VERSION,
+    /* szName */
+    "TCP",
+    /* szRCMod */
+    "",
+    /* szR0Mod */
+    "",
+    /* pszDescription */
+    "TCP serial stream driver.",
+    /* fFlags */
+    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
+    /* fClass. */
+    PDM_DRVREG_CLASS_STREAM,
+    /* cMaxInstances */
+    ~0U,
+    /* cbInstance */
+    sizeof(DRVTCP),
+    /* pfnConstruct */
+    drvTCPConstruct,
+    /* pfnDestruct */
+    drvTCPDestruct,
+    /* pfnRelocate */
+    NULL,
+    /* pfnIOCtl */
+    NULL,
+    /* pfnPowerOn */
+    NULL,
+    /* pfnReset */
+    NULL,
+    /* pfnSuspend */
+    NULL,
+    /* pfnResume */
+    NULL,
+    /* pfnAttach */
+    NULL,
+    /* pfnDetach */
+    NULL,
+    /* pfnPowerOff */
+    drvTCPPowerOff,
+    /* pfnSoftReset */
+    NULL,
+    /* u32EndVersion */
+    PDM_DRVREG_VERSION
+};
+
diff --git a/src/VBox/Devices/build/VBoxDD.cpp b/src/VBox/Devices/build/VBoxDD.cpp
index 94fc626..04b6e6c 100644
--- a/src/VBox/Devices/build/VBoxDD.cpp
+++ b/src/VBox/Devices/build/VBoxDD.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -337,6 +337,9 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvNamedPipe);
     if (RT_FAILURE(rc))
         return rc;
+    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvTCP);
+    if (RT_FAILURE(rc))
+        return rc;
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvRawFile);
     if (RT_FAILURE(rc))
         return rc;
diff --git a/src/VBox/Devices/build/VBoxDD.h b/src/VBox/Devices/build/VBoxDD.h
index 0ed3ef4..2c2d72a 100644
--- a/src/VBox/Devices/build/VBoxDD.h
+++ b/src/VBox/Devices/build/VBoxDD.h
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -146,6 +146,7 @@ extern const PDMDRVREG g_DrvHostWebcam;
 #endif
 extern const PDMDRVREG g_DrvChar;
 extern const PDMDRVREG g_DrvNamedPipe;
+extern const PDMDRVREG g_DrvTCP;
 extern const PDMDRVREG g_DrvRawFile;
 extern const PDMDRVREG g_DrvHostParallel;
 extern const PDMDRVREG g_DrvHostSerial;
diff --git a/src/VBox/Disassembler/DisasmTables.cpp b/src/VBox/Disassembler/DisasmTables.cpp
index 40c03d4..a2f9127 100644
--- a/src/VBox/Disassembler/DisasmTables.cpp
+++ b/src/VBox/Disassembler/DisasmTables.cpp
@@ -3016,8 +3016,8 @@ const DISOPCODE g_aMapX86_Group7_mod11_rm001[8] =
     /* 0F 01 MOD=11b */
     OP("vmcall",             0,                  0,          0,          OP_VMCALL,  OP_PARM_NONE,       OP_PARM_NONE,   OP_PARM_NONE,   DISOPTYPE_HARMLESS ),
     OP("mwait %eAX,%eCX",    IDX_ParseFixedReg,  IDX_ParseFixedReg, 0,   OP_MWAIT,   OP_PARM_REG_EAX,    OP_PARM_REG_ECX,OP_PARM_NONE,   DISOPTYPE_HARMLESS ),
-    INVALID_OPCODE,
-    INVALID_OPCODE,
+    INVALID_OPCODE, /* xsetbv */
+    OP("vmmcall",            0,                  0,          0,          OP_VMMCALL, OP_PARM_NONE,       OP_PARM_NONE,   OP_PARM_NONE,   DISOPTYPE_HARMLESS ),
     OP("smsw %Ew",           IDX_ParseModRM,     0,          0,          OP_SMSW,    OP_PARM_Ew,         OP_PARM_NONE,   OP_PARM_NONE,   DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED_NOTRAP),
     INVALID_OPCODE,
     OP("lmsw %Ew",           IDX_ParseModRM,     0,          0,          OP_LMSW,    OP_PARM_Ew,         OP_PARM_NONE,   OP_PARM_NONE,   DISOPTYPE_DANGEROUS | DISOPTYPE_PRIVILEGED),
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/demo/mkdemo.pl b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/demo/mkdemo.pl
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/funcs/tst.index.d.out b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/funcs/tst.index.d.out
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/funcs/tst.substr.d.out b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/funcs/tst.substr.d.out
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_MACRO_UNDEF.invalidargs.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_MACRO_UNDEF.invalidargs.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_OP_LVAL.rdonly.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_OP_LVAL.rdonly.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_OP_WRITE.usepidmacro.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_OP_WRITE.usepidmacro.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.inval.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.inval.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.pid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/err.D_SYNTAX.pid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.arg0.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.arg0.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.assign.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.assign.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.basic.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.basic.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.egid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.egid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.euid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.euid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.gid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.gid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.pgid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.pgid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.pid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.pid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.ppid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.ppid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.projid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.projid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.quite.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.quite.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.sid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.sid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.taskid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.taskid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.trace.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.trace.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.uid.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/scripting/tst.uid.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithBreakPoint.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithBreakPoint.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithChill.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOut.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOut.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOutStr.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithCopyOutStr.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithPanic.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithPanic.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithRaise.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithRaise.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithStop.d b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/speculation/err.D_ACT_SPEC.SpeculateWithStop.d
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh b/src/VBox/ExtPacks/VBoxDTrace/onnv/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh
old mode 100755
new mode 100644
diff --git a/src/VBox/ExtPacks/VBoxDTrace/onnv/lib/libdtrace/common/mkerrtags.sh b/src/VBox/ExtPacks/VBoxDTrace/onnv/lib/libdtrace/common/mkerrtags.sh
old mode 100755
new mode 100644
diff --git a/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStop.cpp b/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStop.cpp
index 19d814a..bf41726 100644
--- a/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStop.cpp
+++ b/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStop.cpp
@@ -50,6 +50,7 @@ typedef struct AUTOSTOPVM
 static HRESULT autostartSaveVMState(ComPtr<IConsole> &console)
 {
     HRESULT rc = S_OK;
+    ComPtr<IMachine> machine;
     ComPtr<IProgress> progress;
 
     do
@@ -82,7 +83,8 @@ static HRESULT autostartSaveVMState(ComPtr<IConsole> &console)
                 break;
         }
 
-        CHECK_ERROR(console, SaveState(progress.asOutParam()));
+        CHECK_ERROR(console, COMGETTER(Machine)(machine.asOutParam()));
+        CHECK_ERROR(machine, SaveState(progress.asOutParam()));
         if (FAILED(rc))
         {
             if (!fPaused)
diff --git a/src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp b/src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp
index 9033aee..01f73e5 100644
--- a/src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp
+++ b/src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp
@@ -47,20 +47,20 @@ DECLHIDDEN(const char *) machineStateToName(MachineState_T machineState, bool fS
             return fShort ? "poweroff"             : "powered off";
         case MachineState_Saved:
             return "saved";
-        case MachineState_Aborted:
-            return "aborted";
         case MachineState_Teleported:
             return "teleported";
+        case MachineState_Aborted:
+            return "aborted";
         case MachineState_Running:
             return "running";
         case MachineState_Paused:
             return "paused";
         case MachineState_Stuck:
             return fShort ? "gurumeditation"       : "guru meditation";
-        case MachineState_LiveSnapshotting:
-            return fShort ? "livesnapshotting"     : "live snapshotting";
         case MachineState_Teleporting:
             return "teleporting";
+        case MachineState_LiveSnapshotting:
+            return fShort ? "livesnapshotting"     : "live snapshotting";
         case MachineState_Starting:
             return "starting";
         case MachineState_Stopping:
@@ -73,16 +73,20 @@ DECLHIDDEN(const char *) machineStateToName(MachineState_T machineState, bool fS
             return fShort ? "teleportingpausedvm"  : "teleporting paused vm";
         case MachineState_TeleportingIn:
             return fShort ? "teleportingin"        : "teleporting (incoming)";
-        case MachineState_RestoringSnapshot:
-            return fShort ? "restoringsnapshot"    : "restoring snapshot";
-        case MachineState_DeletingSnapshot:
-            return fShort ? "deletingsnapshot"     : "deleting snapshot";
         case MachineState_DeletingSnapshotOnline:
             return fShort ? "deletingsnapshotlive" : "deleting snapshot live";
         case MachineState_DeletingSnapshotPaused:
             return fShort ? "deletingsnapshotlivepaused" : "deleting snapshot live paused";
+        case MachineState_OnlineSnapshotting:
+            return fShort ? "onlinesnapshotting"   : "online snapshotting";
+        case MachineState_RestoringSnapshot:
+            return fShort ? "restoringsnapshot"    : "restoring snapshot";
+        case MachineState_DeletingSnapshot:
+            return fShort ? "deletingsnapshot"     : "deleting snapshot";
         case MachineState_SettingUp:
             return fShort ? "settingup"           : "setting up";
+        case MachineState_Snapshotting:
+            return "snapshotting";
         default:
             break;
     }
diff --git a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModAPIMonitor.cpp b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModAPIMonitor.cpp
index f32290a..dc6a7b4 100644
--- a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModAPIMonitor.cpp
+++ b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxModAPIMonitor.cpp
@@ -1,11 +1,10 @@
-
 /* $Id: VBoxModAPIMonitor.cpp $ */
 /** @file
  * VBoxModAPIMonitor - API monitor module for detecting host isolation.
  */
 
 /*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -213,6 +212,9 @@ static int apimonMachineControl(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMach
                 /* Get the associated console. */
                 ComPtr<IConsole> console;
                 CHECK_ERROR_BREAK(g_pSession, COMGETTER(Console)(console.asOutParam()));
+                /* Get the associated session machine. */
+                ComPtr<IMachine> sessionMachine;
+                CHECK_ERROR_BREAK(g_pSession, COMGETTER(Machine)(sessionMachine.asOutParam()));
 
                 ComPtr<IProgress> progress;
 
@@ -268,7 +270,7 @@ static int apimonMachineControl(const Bstr &strUuid, PVBOXWATCHDOG_MACHINE pMach
                                 break;
                         }
 
-                        CHECK_ERROR(console, SaveState(progress.asOutParam()));
+                        CHECK_ERROR(sessionMachine, SaveState(progress.asOutParam()));
                         if (SUCCEEDED(rc))
                         {
                             progress->WaitForCompletion(ulTimeout);
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.cpp b/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
index 362aa83..11817c2 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
@@ -300,6 +300,48 @@ static RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const cha
 
     return rcExit;
 }
+
+RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...)
+{
+    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+    char aszPwdInput[_1K] = { 0 };
+    va_list vaArgs;
+
+    va_start(vaArgs, pszPrompt);
+    int vrc = RTStrmPrintfV(g_pStdOut, pszPrompt, vaArgs);
+    if (RT_SUCCESS(vrc))
+    {
+        bool fEchoOld = false;
+        vrc = RTStrmInputGetEchoChars(g_pStdIn, &fEchoOld);
+        if (RT_SUCCESS(vrc))
+        {
+            vrc = RTStrmInputSetEchoChars(g_pStdIn, false);
+            if (RT_SUCCESS(vrc))
+            {
+                vrc = RTStrmGetLine(g_pStdIn, &aszPwdInput[0], sizeof(aszPwdInput));
+                if (RT_SUCCESS(vrc))
+                    *pPassword = aszPwdInput;
+                else
+                    rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed read password from command line (%Rrc)", vrc);
+
+                int vrc2 = RTStrmInputSetEchoChars(g_pStdIn, fEchoOld);
+                AssertRC(vrc2);
+            }
+            else
+                rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to disable echoing typed characters (%Rrc)", vrc);
+        }
+        else
+            rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to retrieve echo setting (%Rrc)", vrc);
+
+        RTStrmPutStr(g_pStdOut, "\n");
+    }
+    else
+        rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to print prompt (%Rrc)", vrc);
+    va_end(vaArgs);
+
+    return rcExit;
+}
+
 #endif
 
 int main(int argc, char *argv[])
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.h b/src/VBox/Frontends/VBoxManage/VBoxManage.h
index 9abd8f6..7c22052 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManage.h
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.h
@@ -187,6 +187,7 @@ void showLogo(PRTSTREAM pStrm);
 
 #ifndef VBOX_ONLY_DOCS
 RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd);
+RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...);
 
 int handleInternalCommands(HandlerArg *a);
 #endif /* !VBOX_ONLY_DOCS */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
index 77be62f..4e79b9e 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
@@ -1201,6 +1201,33 @@ int handleExportAppliance(HandlerArg *a)
         if (FAILED(rc))
             break;
 
+        /* Query required passwords and supply them to the appliance. */
+        com::SafeArray<BSTR> aIdentifiers;
+
+        CHECK_ERROR_BREAK(pAppliance, GetPasswordIds(ComSafeArrayAsOutParam(aIdentifiers)));
+
+        if (aIdentifiers.size() > 0)
+        {
+            com::SafeArray<BSTR> aPasswords(aIdentifiers.size());
+            RTPrintf("Enter the passwords for the following identifiers to export the apppliance:\n");
+            for (unsigned idxId = 0; idxId < aIdentifiers.size(); idxId++)
+            {
+                com::Utf8Str strPassword;
+                Bstr bstrPassword;
+                Bstr bstrId = aIdentifiers[idxId];
+
+                RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Password ID %s:", Utf8Str(bstrId).c_str());
+                if (rcExit == RTEXITCODE_FAILURE)
+                    return rcExit;
+
+                bstrPassword = strPassword;
+                bstrPassword.detachTo(&aPasswords[idxId]);
+            }
+
+            CHECK_ERROR_BREAK(pAppliance, AddPasswords(ComSafeArrayAsInParam(aIdentifiers),
+                                                       ComSafeArrayAsInParam(aPasswords)));
+        }
+
         if (fManifest)
             options.push_back(ExportOptions_CreateManifest);
 
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
index d886777..5833729 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
@@ -196,7 +196,7 @@ int handleControlVM(HandlerArg *a)
         {
             if (a->argc <= 1 + 1)
             {
-                errorArgument("Missing argument to '%s'. Expected drag'n'drop mode.", a->argv[1]);
+                errorArgument("Missing argument to '%s'. Expected drag and drop mode.", a->argv[1]);
                 rc = E_FAIL;
                 break;
             }
@@ -261,7 +261,7 @@ int handleControlVM(HandlerArg *a)
             }
 
             ComPtr<IProgress> progress;
-            CHECK_ERROR(console, SaveState(progress.asOutParam()));
+            CHECK_ERROR(sessionMachine, SaveState(progress.asOutParam()));
             if (FAILED(rc))
             {
                 if (!fPaused)
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
index bc70383..d189857 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
@@ -51,34 +51,6 @@ static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL, c
     RTMsgError("Error code %Rrc at %s(%u) in function %s", rc, RT_SRC_POS_ARGS);
 }
 
-static int getPassword(const char *pszPrompt, Utf8Str *pPassword)
-{
-    char aszPwdInput[_1K] = { 0 };
-
-    int vrc = RTStrmPutStr(g_pStdOut, pszPrompt);
-    if (RT_SUCCESS(vrc))
-    {
-        bool fEchoOld = false;
-        vrc = RTStrmInputGetEchoChars(g_pStdIn, &fEchoOld);
-        if (RT_SUCCESS(vrc))
-        {
-            vrc = RTStrmInputSetEchoChars(g_pStdIn, false);
-            if (RT_SUCCESS(vrc))
-            {
-                vrc = RTStrmGetLine(g_pStdIn, &aszPwdInput[0], sizeof(aszPwdInput));
-                if (RT_SUCCESS(vrc))
-                    *pPassword = aszPwdInput;
-
-                int vrc2 = RTStrmInputSetEchoChars(g_pStdIn, fEchoOld);
-                AssertRC(vrc2);
-            }
-        }
-        RTStrmPutStr(g_pStdOut, "\n");
-    }
-
-    return vrc;
-}
-
 static int parseMediumVariant(const char *psz, MediumVariant_T *pMediumVariant)
 {
     int rc = VINF_SUCCESS;
@@ -1691,7 +1663,6 @@ static const RTGETOPTDEF g_aEncryptMediumOptions[] =
 int handleEncryptMedium(HandlerArg *a)
 {
     HRESULT rc;
-    int vrc;
     ComPtr<IMedium> hardDisk;
     const char *pszPasswordNew = NULL;
     const char *pszPasswordOld = NULL;
@@ -1766,12 +1737,9 @@ int handleEncryptMedium(HandlerArg *a)
         if (!RTStrCmp(pszPasswordNew, "-"))
         {
             /* Get password from console. */
-            vrc = getPassword("Enter new password:", &strPasswordNew);
-            if (RT_FAILURE(vrc))
-            {
-                RTMsgError("Failed to read new password from standard input");
-                return 1;
-            }
+            RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordNew, "Enter new password:");
+            if (rcExit == RTEXITCODE_FAILURE)
+                return rcExit;
         }
         else
         {
@@ -1789,12 +1757,9 @@ int handleEncryptMedium(HandlerArg *a)
         if (!RTStrCmp(pszPasswordOld, "-"))
         {
             /* Get password from console. */
-            vrc = getPassword("Enter old password:", &strPasswordOld);
-            if (RT_FAILURE(vrc))
-            {
-                RTMsgError("Failed to read old password from standard input");
-                return 1;
-            }
+            RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordOld, "Enter old password:");
+            if (rcExit == RTEXITCODE_FAILURE)
+                return rcExit;
         }
         else
         {
@@ -1843,7 +1808,6 @@ int handleEncryptMedium(HandlerArg *a)
 int handleCheckMediumPassword(HandlerArg *a)
 {
     HRESULT rc;
-    int vrc;
     ComPtr<IMedium> hardDisk;
     const char *pszFilenameOrUuid = NULL;
     Utf8Str strPassword;
@@ -1856,12 +1820,9 @@ int handleCheckMediumPassword(HandlerArg *a)
     if (!RTStrCmp(a->argv[1], "-"))
     {
         /* Get password from console. */
-        vrc = getPassword("Enter password:", &strPassword);
-        if (RT_FAILURE(vrc))
-        {
-            RTMsgError("Failed to read password from standard input");
-            return 1;
-        }
+        RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter password:");
+        if (rcExit == RTEXITCODE_FAILURE)
+            return rcExit;
     }
     else
     {
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
index babc45c..2a05a8e 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
@@ -272,6 +272,8 @@ void printUsage(USAGECATEGORY fCategory, uint32_t fSubCategory, PRTSTREAM pStrm)
                      "                            [--uartmode<1-N> disconnected|\n"
                      "                                             server <pipe>|\n"
                      "                                             client <pipe>|\n"
+                     "                                             tcpserver <port>|\n"
+                     "                                             tcpclient <hostname:port>|\n"
                      "                                             file <file>|\n"
                      "                                             <devicename>]\n"
 #if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
@@ -346,6 +348,7 @@ void printUsage(USAGECATEGORY fCategory, uint32_t fSubCategory, PRTSTREAM pStrm)
         RTStrmPrintf(pStrm,
                      "                            [--usb on|off]\n"
                      "                            [--usbehci on|off]\n"
+                     "                            [--usbxhci on|off]\n"
                      "                            [--snapshotfolder default|<path>]\n"
                      "                            [--teleporter on|off]\n"
                      "                            [--teleporterport <port>]\n"
@@ -438,7 +441,7 @@ void printUsage(USAGECATEGORY fCategory, uint32_t fSubCategory, PRTSTREAM pStrm)
                      "                            [--type gui", SEP);
         if (fVBoxSDL)
             RTStrmPrintf(pStrm, "|sdl");
-        RTStrmPrintf(pStrm, "|headless]\n");
+        RTStrmPrintf(pStrm, "|headless|separate]\n");
         RTStrmPrintf(pStrm,
                      "\n");
     }
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
index 0f63620..aafa967 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
@@ -138,20 +138,20 @@ const char *machineStateToName(MachineState_T machineState, bool fShort)
             return fShort ? "poweroff"             : "powered off";
         case MachineState_Saved:
             return "saved";
-        case MachineState_Aborted:
-            return "aborted";
         case MachineState_Teleported:
             return "teleported";
+        case MachineState_Aborted:
+            return "aborted";
         case MachineState_Running:
             return "running";
         case MachineState_Paused:
             return "paused";
         case MachineState_Stuck:
             return fShort ? "gurumeditation"       : "guru meditation";
-        case MachineState_LiveSnapshotting:
-            return fShort ? "livesnapshotting"     : "live snapshotting";
         case MachineState_Teleporting:
             return "teleporting";
+        case MachineState_LiveSnapshotting:
+            return fShort ? "livesnapshotting"     : "live snapshotting";
         case MachineState_Starting:
             return "starting";
         case MachineState_Stopping:
@@ -164,16 +164,22 @@ const char *machineStateToName(MachineState_T machineState, bool fShort)
             return fShort ? "teleportingpausedvm"  : "teleporting paused vm";
         case MachineState_TeleportingIn:
             return fShort ? "teleportingin"        : "teleporting (incoming)";
-        case MachineState_RestoringSnapshot:
-            return fShort ? "restoringsnapshot"    : "restoring snapshot";
-        case MachineState_DeletingSnapshot:
-            return fShort ? "deletingsnapshot"     : "deleting snapshot";
+        case MachineState_FaultTolerantSyncing:
+            return fShort ? "faulttolerantsyncing" : "fault tolerant syncing";
         case MachineState_DeletingSnapshotOnline:
             return fShort ? "deletingsnapshotlive" : "deleting snapshot live";
         case MachineState_DeletingSnapshotPaused:
             return fShort ? "deletingsnapshotlivepaused" : "deleting snapshot live paused";
+        case MachineState_OnlineSnapshotting:
+            return fShort ? "onlinesnapshotting"   : "online snapshotting";
+        case MachineState_RestoringSnapshot:
+            return fShort ? "restoringsnapshot"    : "restoring snapshot";
+        case MachineState_DeletingSnapshot:
+            return fShort ? "deletingsnapshot"     : "deleting snapshot";
         case MachineState_SettingUp:
-            return fShort ? "settingup"           : "setting up";
+            return fShort ? "settingup"            : "setting up";
+        case MachineState_Snapshotting:
+            return fShort ? "snapshotting"         : "offline snapshotting";
         default:
             break;
     }
@@ -1396,12 +1402,20 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> pVirtualBox,
                         break;
                     case PortMode_RawFile:
                         if (details == VMINFO_MACHINEREADABLE)
-                            RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
+                            RTPrintf("uartmode%d=\"file,%ls\"\n", currentUART + 1,
                                      path.raw());
                         else
                             RTPrintf(", attached to raw file '%ls'\n",
                                      path.raw());
                         break;
+                    case PortMode_TCP:
+                        if (details == VMINFO_MACHINEREADABLE)
+                            RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
+                                     fServer ? "tcpserver" : "tcpclient", path.raw());
+                        else
+                            RTPrintf(", attached to tcp (%s) '%ls'\n",
+                                     fServer ? "server" : "client", path.raw());
+                        break;
                     case PortMode_HostPipe:
                         if (details == VMINFO_MACHINEREADABLE)
                             RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
@@ -1617,7 +1631,7 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> pVirtualBox,
             RTPrintf("Clipboard Mode:  %s\n", psz);
     }
 
-    /* Drag'n'drop */
+    /* Drag and drop */
     {
         const char *psz = "Unknown";
         DnDMode_T enmMode;
@@ -1656,7 +1670,7 @@ HRESULT showVMInfo(ComPtr<IVirtualBox> pVirtualBox,
         if (details == VMINFO_MACHINEREADABLE)
             RTPrintf("draganddrop=\"%s\"\n", psz);
         else
-            RTPrintf("Drag'n'drop Mode: %s\n", psz);
+            RTPrintf("Drag and drop Mode: %s\n", psz);
     }
 
     {
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
index 109b9dc..d42e9f3 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
@@ -649,9 +649,9 @@ int handleDiscardState(HandlerArg *a)
             CHECK_ERROR_BREAK(machine, LockMachine(a->session, LockType_Write));
             do
             {
-                ComPtr<IConsole> console;
-                CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
-                CHECK_ERROR_BREAK(console, DiscardSavedState(true /* fDeleteFile */));
+                ComPtr<IMachine> sessionMachine;
+                CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, DiscardSavedState(true /* fDeleteFile */));
             } while (0);
             CHECK_ERROR_BREAK(a->session, UnlockMachine());
         } while (0);
@@ -686,9 +686,9 @@ int handleAdoptState(HandlerArg *a)
             CHECK_ERROR_BREAK(machine, LockMachine(a->session, LockType_Write));
             do
             {
-                ComPtr<IConsole> console;
-                CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
-                CHECK_ERROR_BREAK(console, AdoptSavedState(Bstr(szStateFileAbs).raw()));
+                ComPtr<IMachine> sessionMachine;
+                CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, AdoptSavedState(Bstr(szStateFileAbs).raw()));
             } while (0);
             CHECK_ERROR_BREAK(a->session, UnlockMachine());
         } while (0);
@@ -806,14 +806,15 @@ int handleSetExtraData(HandlerArg *a)
             /* open an existing session for the VM */
             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
             /* get the session machine */
-            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
+            ComPtr<IMachine> sessionMachine;
+            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), 1);
             /** @todo passing NULL is deprecated */
             if (a->argc < 3)
-                CHECK_ERROR(machine, SetExtraData(Bstr(a->argv[1]).raw(),
-                                                  NULL));
+                CHECK_ERROR(sessionMachine, SetExtraData(Bstr(a->argv[1]).raw(),
+                                                         NULL));
             else if (a->argc == 3)
-                CHECK_ERROR(machine, SetExtraData(Bstr(a->argv[1]).raw(),
-                                                  Bstr(a->argv[2]).raw()));
+                CHECK_ERROR(sessionMachine, SetExtraData(Bstr(a->argv[1]).raw(),
+                                                         Bstr(a->argv[2]).raw()));
             else
                 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
         }
@@ -988,8 +989,11 @@ int handleSharedFolder(HandlerArg *a)
 
             /* open an existing session for the VM */
             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
+
             /* get the session machine */
-            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
+            ComPtr<IMachine> sessionMachine;
+            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), 1);
+
             /* get the session console */
             CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), 1);
 
@@ -1005,13 +1009,14 @@ int handleSharedFolder(HandlerArg *a)
             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
 
             /* get the mutable session machine */
-            a->session->COMGETTER(Machine)(machine.asOutParam());
+            ComPtr<IMachine> sessionMachine;
+            a->session->COMGETTER(Machine)(sessionMachine.asOutParam());
 
-            CHECK_ERROR(machine, CreateSharedFolder(Bstr(name).raw(),
-                                                    Bstr(hostpath).raw(),
-                                                    fWritable, fAutoMount));
+            CHECK_ERROR(sessionMachine, CreateSharedFolder(Bstr(name).raw(),
+                                                           Bstr(hostpath).raw(),
+                                                           fWritable, fAutoMount));
             if (SUCCEEDED(rc))
-                CHECK_ERROR(machine, SaveSettings());
+                CHECK_ERROR(sessionMachine, SaveSettings());
 
             a->session->UnlockMachine();
         }
@@ -1055,7 +1060,8 @@ int handleSharedFolder(HandlerArg *a)
             /* open an existing session for the VM */
             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
             /* get the session machine */
-            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
+            ComPtr<IMachine> sessionMachine;
+            CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), 1);
             /* get the session console */
             CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), 1);
 
@@ -1070,12 +1076,13 @@ int handleSharedFolder(HandlerArg *a)
             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
 
             /* get the mutable session machine */
-            a->session->COMGETTER(Machine)(machine.asOutParam());
+            ComPtr<IMachine> sessionMachine;
+            a->session->COMGETTER(Machine)(sessionMachine.asOutParam());
 
-            CHECK_ERROR(machine, RemoveSharedFolder(Bstr(name).raw()));
+            CHECK_ERROR(sessionMachine, RemoveSharedFolder(Bstr(name).raw()));
 
             /* commit and close the session */
-            CHECK_ERROR(machine, SaveSettings());
+            CHECK_ERROR(sessionMachine, SaveSettings());
             a->session->UnlockMachine();
         }
     }
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
index 2b93d37..b48f0a8 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -459,17 +459,14 @@ int handleModifyVM(HandlerArg *a)
     int c;
     HRESULT rc;
     Bstr name;
-    RTGETOPTUNION ValueUnion;
-    RTGETOPTSTATE GetOptState;
-    ComPtr<IMachine> machine;
-    ComPtr<IBIOSSettings> biosSettings;
 
     /* VM ID + at least one parameter. Parameter arguments are checked
      * individually. */
     if (a->argc < 2)
         return errorSyntax(USAGE_MODIFYVM, "Not enough parameters");
 
-    /* try to find the given machine */
+    /* try to find the given sessionMachine */
+    ComPtr<IMachine> machine;
     CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
                                                machine.asOutParam()), 1);
 
@@ -480,13 +477,18 @@ int handleModifyVM(HandlerArg *a)
     /* open a session for the VM */
     CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
 
-    /* get the mutable session machine */
-    CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
-    machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
+    /* get the mutable session sessionMachine */
+    ComPtr<IMachine> sessionMachine;
+    CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), 1);
+
+    ComPtr<IBIOSSettings> biosSettings;
+    sessionMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
 
+    RTGETOPTSTATE GetOptState;
     RTGetOptInit(&GetOptState, a->argc, a->argv, g_aModifyVMOptions,
                  RT_ELEMENTS(g_aModifyVMOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
 
+    RTGETOPTUNION ValueUnion;
     while (   SUCCEEDED (rc)
            && (c = RTGetOpt(&GetOptState, &ValueUnion)))
     {
@@ -494,19 +496,19 @@ int handleModifyVM(HandlerArg *a)
         {
             case MODIFYVM_NAME:
             {
-                CHECK_ERROR(machine, COMSETTER(Name)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(Name)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
             case MODIFYVM_GROUPS:
             {
                 com::SafeArray<BSTR> groups;
                 parseGroups(ValueUnion.psz, &groups);
-                CHECK_ERROR(machine, COMSETTER(Groups)(ComSafeArrayAsInParam(groups)));
+                CHECK_ERROR(sessionMachine, COMSETTER(Groups)(ComSafeArrayAsInParam(groups)));
                 break;
             }
             case MODIFYVM_DESCRIPTION:
             {
-                CHECK_ERROR(machine, COMSETTER(Description)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(Description)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
             case MODIFYVM_OSTYPE:
@@ -516,7 +518,7 @@ int handleModifyVM(HandlerArg *a)
                                                           guestOSType.asOutParam()));
                 if (SUCCEEDED(rc) && guestOSType)
                 {
-                    CHECK_ERROR(machine, COMSETTER(OSTypeId)(Bstr(ValueUnion.psz).raw()));
+                    CHECK_ERROR(sessionMachine, COMSETTER(OSTypeId)(Bstr(ValueUnion.psz).raw()));
                 }
                 else
                 {
@@ -559,25 +561,25 @@ int handleModifyVM(HandlerArg *a)
                     break;
                 }
                 RTFileClose(iconFile);
-                CHECK_ERROR(machine, COMSETTER(Icon)(ComSafeArrayAsInParam(icon)));
+                CHECK_ERROR(sessionMachine, COMSETTER(Icon)(ComSafeArrayAsInParam(icon)));
                 break;
             }
 
             case MODIFYVM_MEMORY:
             {
-                CHECK_ERROR(machine, COMSETTER(MemorySize)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(MemorySize)(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_PAGEFUSION:
             {
-                CHECK_ERROR(machine, COMSETTER(PageFusionEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(PageFusionEnabled)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_VRAM:
             {
-                CHECK_ERROR(machine, COMSETTER(VRAMSize)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(VRAMSize)(ValueUnion.u32));
                 break;
             }
 
@@ -585,23 +587,23 @@ int handleModifyVM(HandlerArg *a)
             {
                 if (!RTStrICmp(ValueUnion.psz, "efi"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(FirmwareType)(FirmwareType_EFI));
+                    CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "efi32"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(FirmwareType)(FirmwareType_EFI32));
+                    CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI32));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "efi64"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(FirmwareType)(FirmwareType_EFI64));
+                    CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI64));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "efidual"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(FirmwareType)(FirmwareType_EFIDUAL));
+                    CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFIDUAL));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "bios"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(FirmwareType)(FirmwareType_BIOS));
+                    CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_BIOS));
                 }
                 else
                 {
@@ -625,25 +627,25 @@ int handleModifyVM(HandlerArg *a)
 
             case MODIFYVM_PAE:
             {
-                CHECK_ERROR(machine, SetCPUProperty(CPUPropertyType_PAE, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_PAE, ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_LONGMODE:
             {
-                CHECK_ERROR(machine, SetCPUProperty(CPUPropertyType_LongMode, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_LongMode, ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_SYNTHCPU:
             {
-                CHECK_ERROR(machine, SetCPUProperty(CPUPropertyType_Synthetic, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_Synthetic, ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_TFRESET:
             {
-                CHECK_ERROR(machine, SetCPUProperty(CPUPropertyType_TripleFaultReset, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_TripleFaultReset, ValueUnion.f));
                 break;
             }
 
@@ -651,17 +653,17 @@ int handleModifyVM(HandlerArg *a)
             {
                 if (   !RTStrICmp(ValueUnion.psz, "none")
                     || !RTStrICmp(ValueUnion.psz, "disabled"))
-                    CHECK_ERROR(machine, COMSETTER(ParavirtProvider)(ParavirtProvider_None));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_None));
                 else if (!RTStrICmp(ValueUnion.psz, "default"))
-                    CHECK_ERROR(machine, COMSETTER(ParavirtProvider)(ParavirtProvider_Default));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Default));
                 else if (!RTStrICmp(ValueUnion.psz, "legacy"))
-                    CHECK_ERROR(machine, COMSETTER(ParavirtProvider)(ParavirtProvider_Legacy));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Legacy));
                 else if (!RTStrICmp(ValueUnion.psz, "minimal"))
-                    CHECK_ERROR(machine, COMSETTER(ParavirtProvider)(ParavirtProvider_Minimal));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Minimal));
                 else if (!RTStrICmp(ValueUnion.psz, "hyperv"))
-                    CHECK_ERROR(machine, COMSETTER(ParavirtProvider)(ParavirtProvider_HyperV));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_HyperV));
                 else if (!RTStrICmp(ValueUnion.psz, "kvm"))
-                    CHECK_ERROR(machine, COMSETTER(ParavirtProvider)(ParavirtProvider_KVM));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_KVM));
                 else
                 {
                     errorArgument("Invalid --paravirtprovider argument '%s'", ValueUnion.psz);
@@ -672,7 +674,7 @@ int handleModifyVM(HandlerArg *a)
 
             case MODIFYVM_HWVIRTEX:
             {
-                CHECK_ERROR(machine, SetHWVirtExProperty(HWVirtExPropertyType_Enabled, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_Enabled, ValueUnion.f));
                 break;
             }
 
@@ -690,79 +692,79 @@ int handleModifyVM(HandlerArg *a)
                                            GetOptState.pDef->pszLong);
                     aValue[i] = ValueUnion.u32;
                 }
-                CHECK_ERROR(machine, SetCPUIDLeaf(id, aValue[0], aValue[1], aValue[2], aValue[3]));
+                CHECK_ERROR(sessionMachine, SetCPUIDLeaf(id, aValue[0], aValue[1], aValue[2], aValue[3]));
                 break;
             }
 
             case MODIFYVM_DELCPUID:
             {
-                CHECK_ERROR(machine, RemoveCPUIDLeaf(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_DELALLCPUID:
             {
-                CHECK_ERROR(machine, RemoveAllCPUIDLeaves());
+                CHECK_ERROR(sessionMachine, RemoveAllCPUIDLeaves());
                 break;
             }
 
             case MODIFYVM_NESTEDPAGING:
             {
-                CHECK_ERROR(machine, SetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_LARGEPAGES:
             {
-                CHECK_ERROR(machine, SetHWVirtExProperty(HWVirtExPropertyType_LargePages, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_LargePages, ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_VTXVPID:
             {
-                CHECK_ERROR(machine, SetHWVirtExProperty(HWVirtExPropertyType_VPID, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VPID, ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_VTXUX:
             {
-                CHECK_ERROR(machine, SetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, ValueUnion.f));
+                CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_CPUS:
             {
-                CHECK_ERROR(machine, COMSETTER(CPUCount)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(CPUCount)(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_RTCUSEUTC:
             {
-                CHECK_ERROR(machine, COMSETTER(RTCUseUTC)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(RTCUseUTC)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_CPUHOTPLUG:
             {
-                CHECK_ERROR(machine, COMSETTER(CPUHotPlugEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(CPUHotPlugEnabled)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_PLUGCPU:
             {
-                CHECK_ERROR(machine, HotPlugCPU(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, HotPlugCPU(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_UNPLUGCPU:
             {
-                CHECK_ERROR(machine, HotUnplugCPU(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, HotUnplugCPU(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_CPU_EXECTUION_CAP:
             {
-                CHECK_ERROR(machine, COMSETTER(CPUExecutionCap)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(CPUExecutionCap)(ValueUnion.u32));
                 break;
             }
 
@@ -770,16 +772,16 @@ int handleModifyVM(HandlerArg *a)
             {
                 if (   !RTStrICmp(ValueUnion.psz, "none")
                     || !RTStrICmp(ValueUnion.psz, "disabled"))
-                    CHECK_ERROR(machine, COMSETTER(GraphicsControllerType)(GraphicsControllerType_Null));
+                    CHECK_ERROR(sessionMachine, COMSETTER(GraphicsControllerType)(GraphicsControllerType_Null));
                 else if (   !RTStrICmp(ValueUnion.psz, "vboxvga")
                          || !RTStrICmp(ValueUnion.psz, "vbox")
                          || !RTStrICmp(ValueUnion.psz, "vga")
                          || !RTStrICmp(ValueUnion.psz, "vesa"))
-                    CHECK_ERROR(machine, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxVGA));
+                    CHECK_ERROR(sessionMachine, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxVGA));
 #ifdef VBOX_WITH_VMSVGA
                 else if (   !RTStrICmp(ValueUnion.psz, "vmsvga")
                          || !RTStrICmp(ValueUnion.psz, "vmware"))
-                    CHECK_ERROR(machine, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VMSVGA));
+                    CHECK_ERROR(sessionMachine, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VMSVGA));
 #endif
                 else
                 {
@@ -791,20 +793,20 @@ int handleModifyVM(HandlerArg *a)
 
             case MODIFYVM_MONITORCOUNT:
             {
-                CHECK_ERROR(machine, COMSETTER(MonitorCount)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(MonitorCount)(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_ACCELERATE3D:
             {
-                CHECK_ERROR(machine, COMSETTER(Accelerate3DEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(Accelerate3DEnabled)(ValueUnion.f));
                 break;
             }
 
 #ifdef VBOX_WITH_VIDEOHWACCEL
             case MODIFYVM_ACCELERATE2DVIDEO:
             {
-                CHECK_ERROR(machine, COMSETTER(Accelerate2DVideoEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(Accelerate2DVideoEnabled)(ValueUnion.f));
                 break;
             }
 #endif
@@ -871,23 +873,23 @@ int handleModifyVM(HandlerArg *a)
             {
                 if (!RTStrICmp(ValueUnion.psz, "none"))
                 {
-                    CHECK_ERROR(machine, SetBootOrder(GetOptState.uIndex, DeviceType_Null));
+                    CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Null));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "floppy"))
                 {
-                    CHECK_ERROR(machine, SetBootOrder(GetOptState.uIndex, DeviceType_Floppy));
+                    CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Floppy));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "dvd"))
                 {
-                    CHECK_ERROR(machine, SetBootOrder(GetOptState.uIndex, DeviceType_DVD));
+                    CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_DVD));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "disk"))
                 {
-                    CHECK_ERROR(machine, SetBootOrder(GetOptState.uIndex, DeviceType_HardDisk));
+                    CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_HardDisk));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "net"))
                 {
-                    CHECK_ERROR(machine, SetBootOrder(GetOptState.uIndex, DeviceType_Network));
+                    CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Network));
                 }
                 else
                     return errorArgument("Invalid boot device '%s'", ValueUnion.psz);
@@ -926,7 +928,7 @@ int handleModifyVM(HandlerArg *a)
 
                 if (!RTStrICmp(ValueUnion.psz, "none"))
                 {
-                    machine->DetachDevice(bstrController.raw(), u1, u2);
+                    sessionMachine->DetachDevice(bstrController.raw(), u1, u2);
                 }
                 else
                 {
@@ -939,7 +941,7 @@ int handleModifyVM(HandlerArg *a)
                         break;
                     if (hardDisk)
                     {
-                        CHECK_ERROR(machine, AttachDevice(bstrController.raw(),
+                        CHECK_ERROR(sessionMachine, AttachDevice(bstrController.raw(),
                                                           u1, u2,
                                                           DeviceType_HardDisk,
                                                           hardDisk));
@@ -953,7 +955,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_IDECONTROLLER: // deprecated
             {
                 ComPtr<IStorageController> storageController;
-                CHECK_ERROR(machine, GetStorageControllerByName(Bstr("IDE Controller").raw(),
+                CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("IDE Controller").raw(),
                                                                  storageController.asOutParam()));
 
                 if (!RTStrICmp(ValueUnion.psz, "PIIX3"))
@@ -979,7 +981,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_SATAPORTCOUNT: // deprecated
             {
                 ComPtr<IStorageController> SataCtl;
-                CHECK_ERROR(machine, GetStorageControllerByName(Bstr("SATA").raw(),
+                CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("SATA").raw(),
                                                                 SataCtl.asOutParam()));
 
                 if (SUCCEEDED(rc) && ValueUnion.u32 > 0)
@@ -992,13 +994,13 @@ int handleModifyVM(HandlerArg *a)
                 if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable"))
                 {
                     ComPtr<IStorageController> ctl;
-                    CHECK_ERROR(machine, AddStorageController(Bstr("SATA").raw(),
+                    CHECK_ERROR(sessionMachine, AddStorageController(Bstr("SATA").raw(),
                                                               StorageBus_SATA,
                                                               ctl.asOutParam()));
                     CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
-                    CHECK_ERROR(machine, RemoveStorageController(Bstr("SATA").raw()));
+                    CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("SATA").raw()));
                 else
                     return errorArgument("Invalid --usb argument '%s'", ValueUnion.psz);
                 break;
@@ -1008,10 +1010,10 @@ int handleModifyVM(HandlerArg *a)
             {
                 if (!RTStrICmp(ValueUnion.psz, "none"))
                 {
-                    rc = machine->DetachDevice(Bstr("LsiLogic").raw(),
+                    rc = sessionMachine->DetachDevice(Bstr("LsiLogic").raw(),
                                                GetOptState.uIndex, 0);
                     if (FAILED(rc))
-                        CHECK_ERROR(machine, DetachDevice(Bstr("BusLogic").raw(),
+                        CHECK_ERROR(sessionMachine, DetachDevice(Bstr("BusLogic").raw(),
                                                           GetOptState.uIndex, 0));
                 }
                 else
@@ -1025,12 +1027,12 @@ int handleModifyVM(HandlerArg *a)
                         break;
                     if (hardDisk)
                     {
-                        rc = machine->AttachDevice(Bstr("LsiLogic").raw(),
+                        rc = sessionMachine->AttachDevice(Bstr("LsiLogic").raw(),
                                                    GetOptState.uIndex, 0,
                                                    DeviceType_HardDisk,
                                                    hardDisk);
                         if (FAILED(rc))
-                            CHECK_ERROR(machine,
+                            CHECK_ERROR(sessionMachine,
                                         AttachDevice(Bstr("BusLogic").raw(),
                                                      GetOptState.uIndex, 0,
                                                      DeviceType_HardDisk,
@@ -1048,11 +1050,11 @@ int handleModifyVM(HandlerArg *a)
 
                 if (!RTStrICmp(ValueUnion.psz, "LsiLogic"))
                 {
-                    rc = machine->RemoveStorageController(Bstr("BusLogic").raw());
+                    rc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
                     if (FAILED(rc))
-                        CHECK_ERROR(machine, RemoveStorageController(Bstr("LsiLogic").raw()));
+                        CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
 
-                    CHECK_ERROR(machine,
+                    CHECK_ERROR(sessionMachine,
                                  AddStorageController(Bstr("LsiLogic").raw(),
                                                       StorageBus_SCSI,
                                                       ctl.asOutParam()));
@@ -1062,11 +1064,11 @@ int handleModifyVM(HandlerArg *a)
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "BusLogic"))
                 {
-                    rc = machine->RemoveStorageController(Bstr("LsiLogic").raw());
+                    rc = sessionMachine->RemoveStorageController(Bstr("LsiLogic").raw());
                     if (FAILED(rc))
-                        CHECK_ERROR(machine, RemoveStorageController(Bstr("BusLogic").raw()));
+                        CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("BusLogic").raw()));
 
-                    CHECK_ERROR(machine,
+                    CHECK_ERROR(sessionMachine,
                                  AddStorageController(Bstr("BusLogic").raw(),
                                                       StorageBus_SCSI,
                                                       ctl.asOutParam()));
@@ -1085,7 +1087,7 @@ int handleModifyVM(HandlerArg *a)
                 {
                     ComPtr<IStorageController> ctl;
 
-                    CHECK_ERROR(machine, AddStorageController(Bstr("BusLogic").raw(),
+                    CHECK_ERROR(sessionMachine, AddStorageController(Bstr("BusLogic").raw(),
                                                               StorageBus_SCSI,
                                                               ctl.asOutParam()));
                     if (SUCCEEDED(rc))
@@ -1093,16 +1095,16 @@ int handleModifyVM(HandlerArg *a)
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
                 {
-                    rc = machine->RemoveStorageController(Bstr("BusLogic").raw());
+                    rc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
                     if (FAILED(rc))
-                        CHECK_ERROR(machine, RemoveStorageController(Bstr("LsiLogic").raw()));
+                        CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
                 }
                 break;
             }
 
             case MODIFYVM_DVDPASSTHROUGH: // deprecated
             {
-                CHECK_ERROR(machine, PassthroughDevice(Bstr("IDE Controller").raw(),
+                CHECK_ERROR(sessionMachine, PassthroughDevice(Bstr("IDE Controller").raw(),
                                                        1, 0,
                                                        !RTStrICmp(ValueUnion.psz, "on")));
                 break;
@@ -1159,7 +1161,7 @@ int handleModifyVM(HandlerArg *a)
                     }
                 }
 
-                CHECK_ERROR(machine, MountMedium(Bstr("IDE Controller").raw(),
+                CHECK_ERROR(sessionMachine, MountMedium(Bstr("IDE Controller").raw(),
                                                  1, 0,
                                                  dvdMedium,
                                                  FALSE /* aForce */));
@@ -1170,7 +1172,7 @@ int handleModifyVM(HandlerArg *a)
             {
                 ComPtr<IMedium> floppyMedium;
                 ComPtr<IMediumAttachment> floppyAttachment;
-                machine->GetMediumAttachment(Bstr("Floppy Controller").raw(),
+                sessionMachine->GetMediumAttachment(Bstr("Floppy Controller").raw(),
                                              0, 0, floppyAttachment.asOutParam());
 
                 /* disable? */
@@ -1178,14 +1180,14 @@ int handleModifyVM(HandlerArg *a)
                 {
                     /* disable the controller */
                     if (floppyAttachment)
-                        CHECK_ERROR(machine, DetachDevice(Bstr("Floppy Controller").raw(),
+                        CHECK_ERROR(sessionMachine, DetachDevice(Bstr("Floppy Controller").raw(),
                                                           0, 0));
                 }
                 else
                 {
                     /* enable the controller */
                     if (!floppyAttachment)
-                        CHECK_ERROR(machine, AttachDeviceWithoutMedium(Bstr("Floppy Controller").raw(),
+                        CHECK_ERROR(sessionMachine, AttachDeviceWithoutMedium(Bstr("Floppy Controller").raw(),
                                                                             0, 0,
                                                                             DeviceType_Floppy));
 
@@ -1223,7 +1225,7 @@ int handleModifyVM(HandlerArg *a)
                             break;
                         }
                     }
-                    CHECK_ERROR(machine, MountMedium(Bstr("Floppy Controller").raw(),
+                    CHECK_ERROR(sessionMachine, MountMedium(Bstr("Floppy Controller").raw(),
                                                      0, 0,
                                                      floppyMedium,
                                                      FALSE /* aForce */));
@@ -1238,7 +1240,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMSETTER(TraceFile)(Bstr(ValueUnion.psz).raw()));
@@ -1251,7 +1253,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMSETTER(TraceEnabled)(ValueUnion.f));
@@ -1264,7 +1266,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 if (nic)
@@ -1303,7 +1305,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 if (!RTStrICmp(ValueUnion.psz, "Am79C970A"))
@@ -1348,7 +1350,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMSETTER(LineSpeed)(ValueUnion.u32));
@@ -1361,7 +1363,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 /* Somewhat arbitrary limitation - we can pass a list of up to 4 PCI devices
@@ -1401,7 +1403,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMSETTER(PromiscModePolicy)(enmPromiscModePolicy));
@@ -1414,7 +1416,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 if (!RTStrICmp(ValueUnion.psz, "none"))
@@ -1427,7 +1429,7 @@ int handleModifyVM(HandlerArg *a)
                     ComPtr<IBandwidthControl> bwCtrl;
                     ComPtr<IBandwidthGroup> bwGroup;
 
-                    CHECK_ERROR(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
+                    CHECK_ERROR(sessionMachine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
 
                     if (SUCCEEDED(rc))
                     {
@@ -1447,7 +1449,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 if (!RTStrICmp(ValueUnion.psz, "none"))
@@ -1507,7 +1509,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMSETTER(CableConnected)(ValueUnion.f));
@@ -1520,7 +1522,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 /* remove it? */
@@ -1541,7 +1543,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 /* remove it? */
@@ -1562,7 +1564,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 /* remove it? */
@@ -1583,7 +1585,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMSETTER(GenericDriver)(Bstr(ValueUnion.psz).raw()));
@@ -1596,7 +1598,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMSETTER(NATNetwork)(Bstr(ValueUnion.psz).raw()));
@@ -1609,7 +1611,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1629,7 +1631,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1679,7 +1681,7 @@ int handleModifyVM(HandlerArg *a)
                 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
                     break;
 
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
@@ -1695,7 +1697,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1758,7 +1760,7 @@ int handleModifyVM(HandlerArg *a)
                 ComPtr<INATEngine> engine;
                 uint32_t aliasMode = 0;
 
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
@@ -1791,7 +1793,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1807,7 +1809,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1823,7 +1825,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1838,7 +1840,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1854,7 +1856,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1870,7 +1872,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 ComPtr<INATEngine> engine;
@@ -1885,7 +1887,7 @@ int handleModifyVM(HandlerArg *a)
                     break;
 
                 ComPtr<INetworkAdapter> nic;
-                CHECK_ERROR_BREAK(machine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
                 ASSERT(nic);
 
                 /* generate one? */
@@ -1905,23 +1907,23 @@ int handleModifyVM(HandlerArg *a)
                 bool fEnableUsb = false;
                 if (!RTStrICmp(ValueUnion.psz, "ps2"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(PointingHIDType)(PointingHIDType_PS2Mouse));
+                    CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_PS2Mouse));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "usb"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(PointingHIDType)(PointingHIDType_USBMouse));
+                    CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMouse));
                     if (SUCCEEDED(rc))
                         fEnableUsb = true;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "usbtablet"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(PointingHIDType)(PointingHIDType_USBTablet));
+                    CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBTablet));
                     if (SUCCEEDED(rc))
                         fEnableUsb = true;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "usbmultitouch"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouch));
+                    CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouch));
                     if (SUCCEEDED(rc))
                         fEnableUsb = true;
                 }
@@ -1934,12 +1936,12 @@ int handleModifyVM(HandlerArg *a)
                 {
                     /* Make sure the OHCI controller is enabled. */
                     ULONG cOhciCtrls = 0;
-                    rc = machine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
+                    rc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
                     if (   SUCCEEDED(rc)
                         && !cOhciCtrls)
                     {
                         ComPtr<IUSBController> UsbCtl;
-                        CHECK_ERROR(machine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
+                        CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
                                                               UsbCtl.asOutParam()));
                     }
                 }
@@ -1951,11 +1953,11 @@ int handleModifyVM(HandlerArg *a)
                 bool fEnableUsb = false;
                 if (!RTStrICmp(ValueUnion.psz, "ps2"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_PS2Keyboard));
+                    CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_PS2Keyboard));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "usb"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_USBKeyboard));
+                    CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_USBKeyboard));
                     if (SUCCEEDED(rc))
                         fEnableUsb = true;
                 }
@@ -1968,12 +1970,12 @@ int handleModifyVM(HandlerArg *a)
                 {
                     /* Make sure the OHCI controller is enabled. */
                     ULONG cOhciCtrls = 0;
-                    rc = machine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
+                    rc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
                     if (   SUCCEEDED(rc)
                         && !cOhciCtrls)
                     {
                         ComPtr<IUSBController> UsbCtl;
-                        CHECK_ERROR(machine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
+                        CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
                                                               UsbCtl.asOutParam()));
                     }
                 }
@@ -1985,7 +1987,7 @@ int handleModifyVM(HandlerArg *a)
                 ComPtr<ISerialPort> uart;
                 char *pszIRQ = NULL;
 
-                CHECK_ERROR_BREAK(machine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
                 ASSERT(uart);
 
                 if (!RTStrICmp(ValueUnion.psz, "disconnected"))
@@ -1994,6 +1996,8 @@ int handleModifyVM(HandlerArg *a)
                 }
                 else if (   !RTStrICmp(ValueUnion.psz, "server")
                          || !RTStrICmp(ValueUnion.psz, "client")
+                         || !RTStrICmp(ValueUnion.psz, "tcpserver")
+                         || !RTStrICmp(ValueUnion.psz, "tcpclient")
                          || !RTStrICmp(ValueUnion.psz, "file"))
                 {
                     const char *pszMode = ValueUnion.psz;
@@ -2016,6 +2020,16 @@ int handleModifyVM(HandlerArg *a)
                         CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
                         CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
                     }
+                    else if (!RTStrICmp(pszMode, "tcpserver"))
+                    {
+                        CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
+                        CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
+                    }
+                    else if (!RTStrICmp(pszMode, "tcpclient"))
+                    {
+                        CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
+                        CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
+                    }
                     else if (!RTStrICmp(pszMode, "file"))
                     {
                         CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_RawFile));
@@ -2033,7 +2047,7 @@ int handleModifyVM(HandlerArg *a)
             {
                 ComPtr<ISerialPort> uart;
 
-                CHECK_ERROR_BREAK(machine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
                 ASSERT(uart);
 
                 if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
@@ -2067,7 +2081,7 @@ int handleModifyVM(HandlerArg *a)
                 ComPtr<IParallelPort> lpt;
                 char *pszIRQ = NULL;
 
-                CHECK_ERROR_BREAK(machine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
                 ASSERT(lpt);
 
                 CHECK_ERROR(lpt, COMSETTER(Path)(Bstr(ValueUnion.psz).raw()));
@@ -2078,7 +2092,7 @@ int handleModifyVM(HandlerArg *a)
             {
                 ComPtr<IParallelPort> lpt;
 
-                CHECK_ERROR_BREAK(machine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
                 ASSERT(lpt);
 
                 if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
@@ -2109,14 +2123,14 @@ int handleModifyVM(HandlerArg *a)
 
             case MODIFYVM_GUESTMEMORYBALLOON:
             {
-                CHECK_ERROR(machine, COMSETTER(MemoryBalloonSize)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(MemoryBalloonSize)(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_AUDIOCONTROLLER:
             {
                 ComPtr<IAudioAdapter> audioAdapter;
-                machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
+                sessionMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
                 ASSERT(audioAdapter);
 
                 if (!RTStrICmp(ValueUnion.psz, "sb16"))
@@ -2136,7 +2150,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_AUDIO:
             {
                 ComPtr<IAudioAdapter> audioAdapter;
-                machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
+                sessionMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
                 ASSERT(audioAdapter);
 
                 /* disable? */
@@ -2241,7 +2255,7 @@ int handleModifyVM(HandlerArg *a)
                 }
                 if (SUCCEEDED(rc))
                 {
-                    CHECK_ERROR(machine, COMSETTER(ClipboardMode)(mode));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ClipboardMode)(mode));
                 }
                 break;
             }
@@ -2264,7 +2278,7 @@ int handleModifyVM(HandlerArg *a)
                 }
                 if (SUCCEEDED(rc))
                 {
-                    CHECK_ERROR(machine, COMSETTER(DnDMode)(mode));
+                    CHECK_ERROR(sessionMachine, COMSETTER(DnDMode)(mode));
                 }
                 break;
             }
@@ -2272,7 +2286,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDE_EXTPACK:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 if (vrdeServer)
@@ -2291,7 +2305,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEPROPERTY:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 if (vrdeServer)
@@ -2334,7 +2348,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEPORT:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 if (!RTStrICmp(ValueUnion.psz, "default"))
@@ -2350,7 +2364,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEADDRESS:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Address").raw(), Bstr(ValueUnion.psz).raw()));
@@ -2362,7 +2376,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEAUTHTYPE:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 if (!RTStrICmp(ValueUnion.psz, "null"))
@@ -2388,7 +2402,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEAUTHLIBRARY:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 if (vrdeServer)
@@ -2409,7 +2423,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEMULTICON:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 CHECK_ERROR(vrdeServer, COMSETTER(AllowMultiConnection)(ValueUnion.f));
@@ -2421,7 +2435,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEREUSECON:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 CHECK_ERROR(vrdeServer, COMSETTER(ReuseSingleConnection)(ValueUnion.f));
@@ -2433,7 +2447,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEVIDEOCHANNEL:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Enabled").raw(),
@@ -2446,7 +2460,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDEVIDEOCHANNELQUALITY:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Quality").raw(),
@@ -2459,7 +2473,7 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_VRDE:
             {
                 ComPtr<IVRDEServer> vrdeServer;
-                machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+                sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
                 ASSERT(vrdeServer);
 
                 CHECK_ERROR(vrdeServer, COMSETTER(Enabled)(ValueUnion.f));
@@ -2469,17 +2483,17 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_USBXHCI:
             {
                 ULONG cXhciCtrls = 0;
-                rc = machine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
+                rc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
                 if (SUCCEEDED(rc))
                 {
                     if (!cXhciCtrls && ValueUnion.f)
                     {
                         ComPtr<IUSBController> UsbCtl;
-                        CHECK_ERROR(machine, AddUSBController(Bstr("XHCI").raw(), USBControllerType_XHCI,
+                        CHECK_ERROR(sessionMachine, AddUSBController(Bstr("XHCI").raw(), USBControllerType_XHCI,
                                                               UsbCtl.asOutParam()));
                     }
                     else if (cXhciCtrls && !ValueUnion.f)
-                        CHECK_ERROR(machine, RemoveUSBController(Bstr("XHCI").raw()));
+                        CHECK_ERROR(sessionMachine, RemoveUSBController(Bstr("XHCI").raw()));
                 }
                 break;
             }
@@ -2487,17 +2501,17 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_USBEHCI:
             {
                 ULONG cEhciCtrls = 0;
-                rc = machine->GetUSBControllerCountByType(USBControllerType_EHCI, &cEhciCtrls);
+                rc = sessionMachine->GetUSBControllerCountByType(USBControllerType_EHCI, &cEhciCtrls);
                 if (SUCCEEDED(rc))
                 {
                     if (!cEhciCtrls && ValueUnion.f)
                     {
                         ComPtr<IUSBController> UsbCtl;
-                        CHECK_ERROR(machine, AddUSBController(Bstr("EHCI").raw(), USBControllerType_EHCI,
+                        CHECK_ERROR(sessionMachine, AddUSBController(Bstr("EHCI").raw(), USBControllerType_EHCI,
                                                               UsbCtl.asOutParam()));
                     }
                     else if (cEhciCtrls && !ValueUnion.f)
-                        CHECK_ERROR(machine, RemoveUSBController(Bstr("EHCI").raw()));
+                        CHECK_ERROR(sessionMachine, RemoveUSBController(Bstr("EHCI").raw()));
                 }
                 break;
             }
@@ -2505,17 +2519,17 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_USB:
             {
                 ULONG cOhciCtrls = 0;
-                rc = machine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
+                rc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
                 if (SUCCEEDED(rc))
                 {
                     if (!cOhciCtrls && ValueUnion.f)
                     {
                         ComPtr<IUSBController> UsbCtl;
-                        CHECK_ERROR(machine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
+                        CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
                                                               UsbCtl.asOutParam()));
                     }
                     else if (cOhciCtrls && !ValueUnion.f)
-                        CHECK_ERROR(machine, RemoveUSBController(Bstr("OHCI").raw()));
+                        CHECK_ERROR(sessionMachine, RemoveUSBController(Bstr("OHCI").raw()));
                 }
                 break;
             }
@@ -2523,33 +2537,33 @@ int handleModifyVM(HandlerArg *a)
             case MODIFYVM_SNAPSHOTFOLDER:
             {
                 if (!RTStrICmp(ValueUnion.psz, "default"))
-                    CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr().raw()));
+                    CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr().raw()));
                 else
-                    CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr(ValueUnion.psz).raw()));
+                    CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
 
             case MODIFYVM_TELEPORTER_ENABLED:
             {
-                CHECK_ERROR(machine, COMSETTER(TeleporterEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(TeleporterEnabled)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_TELEPORTER_PORT:
             {
-                CHECK_ERROR(machine, COMSETTER(TeleporterPort)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPort)(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_TELEPORTER_ADDRESS:
             {
-                CHECK_ERROR(machine, COMSETTER(TeleporterAddress)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(TeleporterAddress)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
 
             case MODIFYVM_TELEPORTER_PASSWORD:
             {
-                CHECK_ERROR(machine, COMSETTER(TeleporterPassword)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
 
@@ -2560,25 +2574,25 @@ int handleModifyVM(HandlerArg *a)
                 if (rcExit != RTEXITCODE_SUCCESS)
                     rc = E_FAIL;
                 else
-                    CHECK_ERROR(machine, COMSETTER(TeleporterPassword)(Bstr(password).raw()));
+                    CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(password).raw()));
                 break;
             }
 
             case MODIFYVM_TRACING_ENABLED:
             {
-                CHECK_ERROR(machine, COMSETTER(TracingEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(TracingEnabled)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_TRACING_CONFIG:
             {
-                CHECK_ERROR(machine, COMSETTER(TracingConfig)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(TracingConfig)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
 
             case MODIFYVM_TRACING_ALLOW_VM_ACCESS:
             {
-                CHECK_ERROR(machine, COMSETTER(AllowTracingToAccessVM)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(AllowTracingToAccessVM)(ValueUnion.f));
                 break;
             }
 
@@ -2586,12 +2600,12 @@ int handleModifyVM(HandlerArg *a)
             {
                 if (!RTStrICmp(ValueUnion.psz, "master"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(FaultToleranceState(FaultToleranceState_Master)));
+                    CHECK_ERROR(sessionMachine, COMSETTER(FaultToleranceState(FaultToleranceState_Master)));
                 }
                 else
                 if (!RTStrICmp(ValueUnion.psz, "standby"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(FaultToleranceState(FaultToleranceState_Standby)));
+                    CHECK_ERROR(sessionMachine, COMSETTER(FaultToleranceState(FaultToleranceState_Standby)));
                 }
                 else
                 {
@@ -2603,49 +2617,49 @@ int handleModifyVM(HandlerArg *a)
 
             case MODIFYVM_FAULT_TOLERANCE_ADDRESS:
             {
-                CHECK_ERROR(machine, COMSETTER(FaultToleranceAddress)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(FaultToleranceAddress)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
 
             case MODIFYVM_FAULT_TOLERANCE_PORT:
             {
-                CHECK_ERROR(machine, COMSETTER(FaultTolerancePort)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(FaultTolerancePort)(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_FAULT_TOLERANCE_PASSWORD:
             {
-                CHECK_ERROR(machine, COMSETTER(FaultTolerancePassword)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(FaultTolerancePassword)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
 
             case MODIFYVM_FAULT_TOLERANCE_SYNC_INTERVAL:
             {
-                CHECK_ERROR(machine, COMSETTER(FaultToleranceSyncInterval)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(FaultToleranceSyncInterval)(ValueUnion.u32));
                 break;
             }
 
             case MODIFYVM_HARDWARE_UUID:
             {
-                CHECK_ERROR(machine, COMSETTER(HardwareUUID)(Bstr(ValueUnion.psz).raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(HardwareUUID)(Bstr(ValueUnion.psz).raw()));
                 break;
             }
 
             case MODIFYVM_HPET:
             {
-                CHECK_ERROR(machine, COMSETTER(HPETEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(HPETEnabled)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_IOCACHE:
             {
-                CHECK_ERROR(machine, COMSETTER(IOCacheEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(IOCacheEnabled)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_IOCACHESIZE:
             {
-                CHECK_ERROR(machine, COMSETTER(IOCacheSize)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(IOCacheSize)(ValueUnion.u32));
                 break;
             }
 
@@ -2653,11 +2667,11 @@ int handleModifyVM(HandlerArg *a)
             {
                 if (!RTStrICmp(ValueUnion.psz, "piix3"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(ChipsetType)(ChipsetType_PIIX3));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_PIIX3));
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "ich9"))
                 {
-                    CHECK_ERROR(machine, COMSETTER(ChipsetType)(ChipsetType_ICH9));
+                    CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_ICH9));
                     BOOL fIoApic = FALSE;
                     CHECK_ERROR(biosSettings, COMGETTER(IOAPICEnabled)(&fIoApic));
                     if (!fIoApic)
@@ -2676,13 +2690,13 @@ int handleModifyVM(HandlerArg *a)
 #ifdef VBOX_WITH_VPX
             case MODIFYVM_VCP:
             {
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureEnabled)(ValueUnion.f));
                 break;
             }
             case MODIFYVM_VCP_SCREENS:
             {
                 ULONG cMonitors = 64;
-                CHECK_ERROR(machine, COMGETTER(MonitorCount)(&cMonitors));
+                CHECK_ERROR(sessionMachine, COMGETTER(MonitorCount)(&cMonitors));
                 com::SafeArray<BOOL> screens(cMonitors);
                 if (parseScreens(ValueUnion.psz, &screens))
                 {
@@ -2690,7 +2704,7 @@ int handleModifyVM(HandlerArg *a)
                     rc = E_FAIL;
                     break;
                 }
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureScreens)(ComSafeArrayAsInParam(screens)));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureScreens)(ComSafeArrayAsInParam(screens)));
                 break;
             }
             case MODIFYVM_VCP_FILENAME:
@@ -2709,55 +2723,55 @@ int handleModifyVM(HandlerArg *a)
                     }
                     bstr = szVCFileAbs;
                 }
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureFile)(bstr.raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureFile)(bstr.raw()));
                 break;
             }
             case MODIFYVM_VCP_WIDTH:
             {
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureWidth)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureWidth)(ValueUnion.u32));
                 break;
             }
             case MODIFYVM_VCP_HEIGHT:
             {
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureHeight)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureHeight)(ValueUnion.u32));
                 break;
             }
             case MODIFYVM_VCP_RATE:
             {
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureRate)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureRate)(ValueUnion.u32));
                 break;
             }
             case MODIFYVM_VCP_FPS:
             {
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureFPS)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureFPS)(ValueUnion.u32));
                 break;
             }
             case MODIFYVM_VCP_MAXTIME:
             {
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureMaxTime)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureMaxTime)(ValueUnion.u32));
                 break;
             }
             case MODIFYVM_VCP_MAXSIZE:
             {
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureMaxFileSize)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureMaxFileSize)(ValueUnion.u32));
                 break;
             }
             case MODIFYVM_VCP_OPTIONS:
             {
                 Bstr bstr(ValueUnion.psz);
-                CHECK_ERROR(machine, COMSETTER(VideoCaptureOptions)(bstr.raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureOptions)(bstr.raw()));
                 break;
             }
 #endif
             case MODIFYVM_AUTOSTART_ENABLED:
             {
-                CHECK_ERROR(machine, COMSETTER(AutostartEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(AutostartEnabled)(ValueUnion.f));
                 break;
             }
 
             case MODIFYVM_AUTOSTART_DELAY:
             {
-                CHECK_ERROR(machine, COMSETTER(AutostartDelay)(ValueUnion.u32));
+                CHECK_ERROR(sessionMachine, COMSETTER(AutostartDelay)(ValueUnion.u32));
                 break;
             }
 
@@ -2780,7 +2794,7 @@ int handleModifyVM(HandlerArg *a)
                 }
 
                 if (SUCCEEDED(rc))
-                    CHECK_ERROR(machine, COMSETTER(AutostopType)(enmAutostopType));
+                    CHECK_ERROR(sessionMachine, COMSETTER(AutostopType)(enmAutostopType));
                 break;
             }
 #ifdef VBOX_WITH_PCI_PASSTHROUGH
@@ -2799,7 +2813,7 @@ int handleModifyVM(HandlerArg *a)
                 }
                 else
                 {
-                    CHECK_ERROR(machine, AttachHostPCIDevice(iHostAddr, iGuestAddr, TRUE));
+                    CHECK_ERROR(sessionMachine, AttachHostPCIDevice(iHostAddr, iGuestAddr, TRUE));
                 }
 
                 break;
@@ -2816,7 +2830,7 @@ int handleModifyVM(HandlerArg *a)
                 }
                 else
                 {
-                    CHECK_ERROR(machine, DetachHostPCIDevice(iHostAddr));
+                    CHECK_ERROR(sessionMachine, DetachHostPCIDevice(iHostAddr));
                 }
 
                 break;
@@ -2826,7 +2840,7 @@ int handleModifyVM(HandlerArg *a)
 #ifdef VBOX_WITH_USB_CARDREADER
             case MODIFYVM_USBCARDREADER:
             {
-                CHECK_ERROR(machine, COMSETTER(EmulatedUSBCardReaderEnabled)(ValueUnion.f));
+                CHECK_ERROR(sessionMachine, COMSETTER(EmulatedUSBCardReaderEnabled)(ValueUnion.f));
                 break;
             }
 #endif /* VBOX_WITH_USB_CARDREADER */
@@ -2836,7 +2850,7 @@ int handleModifyVM(HandlerArg *a)
                 Bstr bstr(ValueUnion.psz);
                 if (bstr == "default")
                     bstr = Bstr::Empty;
-                CHECK_ERROR(machine, COMSETTER(DefaultFrontend)(bstr.raw()));
+                CHECK_ERROR(sessionMachine, COMSETTER(DefaultFrontend)(bstr.raw()));
                 break;
             }
 
@@ -2851,7 +2865,7 @@ int handleModifyVM(HandlerArg *a)
 
     /* commit changes */
     if (SUCCEEDED(rc))
-        CHECK_ERROR(machine, SaveSettings());
+        CHECK_ERROR(sessionMachine, SaveSettings());
 
     /* it's important to always close sessions */
     a->session->UnlockMachine();
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
index 22fa47d..aed3be3 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
@@ -197,7 +197,7 @@ static RTEXITCODE handleSnapshotList(HandlerArg *pArgs, ComPtr<IMachine> &pMachi
     if (pSnapshot)
     {
         ComPtr<ISnapshot> pCurrentSnapshot;
-        CHECK_ERROR2_RET(pMachine,COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam()), RTEXITCODE_FAILURE);
+        CHECK_ERROR2_RET(pMachine, COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam()), RTEXITCODE_FAILURE);
         hrc = showSnapshots(pSnapshot, pCurrentSnapshot, enmDetails);
         if (FAILED(hrc))
             return RTEXITCODE_FAILURE;
@@ -280,12 +280,13 @@ int handleSnapshot(HandlerArg *a)
     if (!pMachine)
         return 1;
 
+    /* we have to open a session for this task (new or shared) */
+    CHECK_ERROR_RET(pMachine, LockMachine(a->session, LockType_Shared), 1);
     do
     {
-        /* we have to open a session for this task (new or shared) */
-        rc = pMachine->LockMachine(a->session, LockType_Shared);
-        ComPtr<IConsole> pConsole;
-        CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(pConsole.asOutParam()));
+        /* replace the (read-only) IMachine object by a writable one */
+        ComPtr<IMachine> sessionMachine;
+        CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
 
         /* switch based on the command */
         bool fDelete = false,
@@ -345,35 +346,13 @@ int handleSnapshot(HandlerArg *a)
             if (FAILED(rc))
                 break;
 
-            if (fPause)
-            {
-                MachineState_T machineState;
-                CHECK_ERROR_BREAK(pConsole, COMGETTER(State)(&machineState));
-                if (machineState == MachineState_Running)
-                    CHECK_ERROR_BREAK(pConsole, Pause());
-                else
-                    fPause = false;
-            }
-
             ComPtr<IProgress> progress;
-            CHECK_ERROR_BREAK(pConsole, TakeSnapshot(name.raw(), desc.raw(),
-                                                     progress.asOutParam()));
+            CHECK_ERROR_BREAK(sessionMachine, TakeSnapshot(name.raw(), desc.raw(),
+                                                           fPause,
+                                                           progress.asOutParam()));
 
             rc = showProgress(progress);
             CHECK_PROGRESS_ERROR(progress, ("Failed to take snapshot"));
-
-            if (fPause)
-            {
-                MachineState_T machineState;
-                CHECK_ERROR_BREAK(pConsole, COMGETTER(State)(&machineState));
-                if (machineState == MachineState_Paused)
-                {
-                    if (SUCCEEDED(rc))
-                        CHECK_ERROR_BREAK(pConsole, Resume());
-                    else
-                        pConsole->Resume();
-                }
-            }
         }
         else if (    (fDelete = !strcmp(a->argv[1], "delete"))
                   || (fRestore = !strcmp(a->argv[1], "restore"))
@@ -403,12 +382,12 @@ int handleSnapshot(HandlerArg *a)
 
             if (fRestoreCurrent)
             {
-                CHECK_ERROR_BREAK(pMachine, COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam()));
             }
             else
             {
                 // restore or delete snapshot: then resolve cmd line argument to snapshot instance
-                CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
+                CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
                                                          pSnapshot.asOutParam()));
             }
 
@@ -416,14 +395,14 @@ int handleSnapshot(HandlerArg *a)
 
             if (fDelete)
             {
-                CHECK_ERROR_BREAK(pConsole, DeleteSnapshot(bstrSnapGuid.raw(),
+                CHECK_ERROR_BREAK(sessionMachine, DeleteSnapshot(bstrSnapGuid.raw(),
                                                            pProgress.asOutParam()));
             }
             else
             {
                 // restore or restore current
                 RTPrintf("Restoring snapshot %ls\n", bstrSnapGuid.raw());
-                CHECK_ERROR_BREAK(pConsole, RestoreSnapshot(pSnapshot, pProgress.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, RestoreSnapshot(pSnapshot, pProgress.asOutParam()));
             }
 
             rc = showProgress(pProgress);
@@ -443,11 +422,11 @@ int handleSnapshot(HandlerArg *a)
             if (   !strcmp(a->argv[2], "--current")
                 || !strcmp(a->argv[2], "-current"))
             {
-                CHECK_ERROR_BREAK(pMachine, COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam()));
+                CHECK_ERROR_BREAK(sessionMachine, COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam()));
             }
             else
             {
-                CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
+                CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
                                                          pSnapshot.asOutParam()));
             }
 
@@ -501,8 +480,8 @@ int handleSnapshot(HandlerArg *a)
 
             ComPtr<ISnapshot> pSnapshot;
 
-            CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
-                                                     pSnapshot.asOutParam()));
+            CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
+                                                           pSnapshot.asOutParam()));
 
             /* get the machine of the given snapshot */
             ComPtr<IMachine> pMachine2;
@@ -510,9 +489,9 @@ int handleSnapshot(HandlerArg *a)
             showVMInfo(a->virtualBox, pMachine2, NULL, VMINFO_NONE);
         }
         else if (!strcmp(a->argv[1], "list"))
-            rc = handleSnapshotList(a, pMachine) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+            rc = handleSnapshotList(a, sessionMachine) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
         else if (!strcmp(a->argv[1], "dump"))          // undocumented parameter to debug snapshot info
-            DumpSnapshot(pMachine);
+            DumpSnapshot(sessionMachine);
         else
         {
             errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(a->argv[1]).c_str());
diff --git a/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp b/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
index 1f276c9..afea255 100644
--- a/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
+++ b/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
@@ -207,6 +207,7 @@ static ComPtr<IProgress> gpProgress;
 
 static ULONG       gcMonitors = 1;
 static ComObjPtr<VBoxSDLFB> gpFramebuffer[64];
+static Bstr gaFramebufferId[64];
 static SDL_Cursor *gpDefaultCursor = NULL;
 #ifdef VBOXSDL_WITH_X11
 static Cursor      gpDefaultOrigX11Cursor;
@@ -1836,7 +1837,7 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
         gpMachine->COMGETTER(State)(&machineState);
         if (machineState == MachineState_Saved)
         {
-            CHECK_ERROR(gpConsole, DiscardSavedState(true /* fDeleteFile */));
+            CHECK_ERROR(gpMachine, DiscardSavedState(true /* fDeleteFile */));
         }
         /*
          * If there are snapshots, discard the current state,
@@ -1853,7 +1854,7 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
             if (FAILED(rc))
                 goto leave;
 
-            CHECK_ERROR(gpConsole, RestoreSnapshot(pCurrentSnapshot, gpProgress.asOutParam()));
+            CHECK_ERROR(gpMachine, RestoreSnapshot(pCurrentSnapshot, gpProgress.asOutParam()));
             rc = gpProgress->WaitForCompletion(-1);
         }
     }
@@ -2007,7 +2008,7 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
     for (ULONG i = 0; i < gcMonitors; i++)
     {
         // register our framebuffer
-        rc = gpDisplay->AttachFramebuffer(i, gpFramebuffer[i]);
+        rc = gpDisplay->AttachFramebuffer(i, gpFramebuffer[i], gaFramebufferId[i].asOutParam());
         if (FAILED(rc))
         {
             RTPrintf("Error: could not register framebuffer object!\n");
@@ -3027,7 +3028,7 @@ leave:
     if (gpDisplay)
     {
         for (unsigned i = 0; i < gcMonitors; i++)
-            gpDisplay->DetachFramebuffer(i);
+            gpDisplay->DetachFramebuffer(i, gaFramebufferId[i].raw());
     }
 
     gpMouse = NULL;
@@ -4198,7 +4199,7 @@ void SaveState(void)
     RTThreadYield();
     UpdateTitlebar(TITLEBAR_SAVE);
     gpProgress = NULL;
-    HRESULT rc = gpConsole->SaveState(gpProgress.asOutParam());
+    HRESULT rc = gpMachine->SaveState(gpProgress.asOutParam());
     if (FAILED(rc))
     {
         RTPrintf("Error saving state! rc = 0x%x\n", rc);
@@ -4948,8 +4949,9 @@ static int HandleHostKey(const SDL_KeyboardEvent *pEv)
             RTStrPrintf(pszSnapshotName, sizeof(pszSnapshotName), "Snapshot %d", cSnapshots + 1);
             gpProgress = NULL;
             HRESULT rc;
-            CHECK_ERROR(gpConsole, TakeSnapshot(Bstr(pszSnapshotName).raw(),
+            CHECK_ERROR(gpMachine, TakeSnapshot(Bstr(pszSnapshotName).raw(),
                                                 Bstr("Taken by VBoxSDL").raw(),
+						TRUE,
                                                 gpProgress.asOutParam()));
             if (FAILED(rc))
             {
diff --git a/src/VBox/Frontends/VBoxShell/vboxshell.py b/src/VBox/Frontends/VBoxShell/vboxshell.py
index f336cf1..f7a3cfd 100755
--- a/src/VBox/Frontends/VBoxShell/vboxshell.py
+++ b/src/VBox/Frontends/VBoxShell/vboxshell.py
@@ -30,7 +30,7 @@ Foundation, in version 2 as it comes in the "COPYING" file of the
 VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 """
-__version__ = "$Revision: 98537 $"
+__version__ = "$Revision: 99520 $"
 
 
 import os, sys
@@ -249,9 +249,13 @@ def removeVm(ctx, mach):
     uuid = mach.id
     print "removing machine ", mach.name, "with UUID", uuid
     cmdClosedVm(ctx, mach, detachVmDevice, ["ALL"])
-    mach = mach.unregister(ctx['global'].constants.CleanupMode_Full)
+    disks = mach.unregister(ctx['global'].constants.CleanupMode_Full)
     if mach:
-        mach.deleteSettings()
+        progress = mach.deleteConfig(disks)
+        if progressBar(ctx, progress, 100) and int(progress.resultCode) == 0:
+            print "Success!"
+        else:
+            reportError(ctx, progress)
     # update cache
     getMachines(ctx, True)
 
@@ -717,7 +721,7 @@ def cmdExistingVm(ctx, mach, cmd, args):
            'guest':           lambda: guestExec(ctx, mach, console, args),
            'ginfo':           lambda: ginfo(ctx, console, args),
            'guestlambda':     lambda: args[0](ctx, mach, console, args[1:]),
-           'save':            lambda: progressBar(ctx, console.saveState()),
+           'save':            lambda: progressBar(ctx, session.machine.saveState()),
            'screenshot':      lambda: takeScreenshot(ctx, console, args),
            'teleport':        lambda: teleport(ctx, session, console, args),
            'gueststats':      lambda: guestStats(ctx, console, args),
@@ -2630,7 +2634,7 @@ def snapshotCmd(ctx, args):
             desc = args[4]
         else:
             desc = ""
-        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, console.takeSnapshot(name, desc)))
+        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, mach.takeSnapshot(name, desc, true)))
         return 0
 
     if cmd == 'restore':
@@ -2639,7 +2643,7 @@ def snapshotCmd(ctx, args):
             return 0
         name = args[3]
         snap = mach.findSnapshot(name)
-        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, console.restoreSnapshot(snap)))
+        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, mach.restoreSnapshot(snap)))
         return 0
 
     if cmd == 'restorecurrent':
@@ -2647,7 +2651,7 @@ def snapshotCmd(ctx, args):
             print "usage: snapshot vm restorecurrent"
             return 0
         snap = mach.currentSnapshot()
-        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, console.restoreSnapshot(snap)))
+        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, mach.restoreSnapshot(snap)))
         return 0
 
     if cmd == 'delete':
@@ -2656,7 +2660,7 @@ def snapshotCmd(ctx, args):
             return 0
         name = args[3]
         snap = mach.findSnapshot(name)
-        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, console.deleteSnapshot(snap.id)))
+        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, mach.deleteSnapshot(snap.id)))
         return 0
 
     print "Command '%s' is unknown" % (cmd)
diff --git a/src/VBox/Frontends/VirtualBox/Makefile.kmk b/src/VBox/Frontends/VirtualBox/Makefile.kmk
index 785b2d5..59d340d 100644
--- a/src/VBox/Frontends/VirtualBox/Makefile.kmk
+++ b/src/VBox/Frontends/VirtualBox/Makefile.kmk
@@ -190,7 +190,7 @@ VirtualBox_INCS = \
 # Necessary for the hdd backend enumeration
 VirtualBox_LIBS = $(LIB_DDU)
 
-if1of ($(KBUILD_TARGET), linux freebsd netbsd openbsd)
+if1of ($(KBUILD_TARGET), linux netbsd openbsd)
  VirtualBox_LIBS += dl
 endif
 
diff --git a/src/VBox/Frontends/VirtualBox/src/UIVMInfoDialog.cpp b/src/VBox/Frontends/VirtualBox/src/UIVMInfoDialog.cpp
index 93f804b..f431bbb 100644
--- a/src/VBox/Frontends/VirtualBox/src/UIVMInfoDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/UIVMInfoDialog.cpp
@@ -670,7 +670,7 @@ void UIVMInfoDialog::refreshStatistics()
         }
         strResult += formatValue(tr("VM Uptime"), strUptime, iMaxLength);
         strResult += formatValue(tr("Clipboard Mode"), strClipboardMode, iMaxLength);
-        strResult += formatValue(tr("Drag'n'Drop Mode"), strDnDMode, iMaxLength);
+        strResult += formatValue(tr("Drag and Drop Mode"), strDnDMode, iMaxLength);
         strResult += formatValue(VBoxGlobal::tr("VT-x/AMD-V", "details report"), strVirtualization, iMaxLength);
         strResult += formatValue(VBoxGlobal::tr("Nested Paging", "details report"), strNestedPaging, iMaxLength);
         strResult += formatValue(VBoxGlobal::tr("Unrestricted Execution", "details report"), strUnrestrictedExecution, iMaxLength);
diff --git a/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackend.h b/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackend.h
index 2615544..2be4643 100644
--- a/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackend.h
+++ b/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackend.h
@@ -71,9 +71,7 @@ template<class X> X fromInternalInteger(const int & /* iData */) { Assert(0); re
 template<> bool canConvert<SizeSuffix>();
 template<> bool canConvert<StorageSlot>();
 template<> bool canConvert<UIExtraDataMetaDefs::MenuType>();
-#ifdef Q_WS_MAC
 template<> bool canConvert<UIExtraDataMetaDefs::MenuApplicationActionType>();
-#endif /* Q_WS_MAC */
 template<> bool canConvert<UIExtraDataMetaDefs::MenuHelpActionType>();
 template<> bool canConvert<UIExtraDataMetaDefs::RuntimeMenuMachineActionType>();
 template<> bool canConvert<UIExtraDataMetaDefs::RuntimeMenuViewActionType>();
@@ -95,6 +93,7 @@ template<> bool canConvert<IndicatorType>();
 template<> bool canConvert<MachineCloseAction>();
 template<> bool canConvert<MouseCapturePolicy>();
 template<> bool canConvert<GuruMeditationHandlerType>();
+template<> bool canConvert<ScalingOptimizationType>();
 template<> bool canConvert<HiDPIOptimizationType>();
 #ifndef Q_WS_MAC
 template<> bool canConvert<MiniToolbarAlignment>();
@@ -114,6 +113,7 @@ template<> bool canConvert<KNetworkAttachmentType>();
 template<> bool canConvert<KNetworkAdapterType>();
 template<> bool canConvert<KNetworkAdapterPromiscModePolicy>();
 template<> bool canConvert<KPortMode>();
+template<> bool canConvert<KUSBControllerType>();
 template<> bool canConvert<KUSBDeviceState>();
 template<> bool canConvert<KUSBDeviceFilterAction>();
 template<> bool canConvert<KAudioDriverType>();
@@ -131,10 +131,8 @@ template<> QString toString(const StorageSlot &storageSlot);
 template<> StorageSlot fromString<StorageSlot>(const QString &strStorageSlot);
 template<> QString toInternalString(const UIExtraDataMetaDefs::MenuType &menuType);
 template<> UIExtraDataMetaDefs::MenuType fromInternalString<UIExtraDataMetaDefs::MenuType>(const QString &strMenuType);
-#ifdef Q_WS_MAC
 template<> QString toInternalString(const UIExtraDataMetaDefs::MenuApplicationActionType &menuApplicationActionType);
 template<> UIExtraDataMetaDefs::MenuApplicationActionType fromInternalString<UIExtraDataMetaDefs::MenuApplicationActionType>(const QString &strMenuApplicationActionType);
-#endif /* Q_WS_MAC */
 template<> QString toInternalString(const UIExtraDataMetaDefs::MenuHelpActionType &menuHelpActionType);
 template<> UIExtraDataMetaDefs::MenuHelpActionType fromInternalString<UIExtraDataMetaDefs::MenuHelpActionType>(const QString &strMenuHelpActionType);
 template<> QString toInternalString(const UIExtraDataMetaDefs::RuntimeMenuMachineActionType &runtimeMenuMachineActionType);
@@ -180,6 +178,8 @@ template<> QString toInternalString(const MouseCapturePolicy &mouseCapturePolicy
 template<> MouseCapturePolicy fromInternalString<MouseCapturePolicy>(const QString &strMouseCapturePolicy);
 template<> QString toInternalString(const GuruMeditationHandlerType &guruMeditationHandlerType);
 template<> GuruMeditationHandlerType fromInternalString<GuruMeditationHandlerType>(const QString &strGuruMeditationHandlerType);
+template<> QString toInternalString(const ScalingOptimizationType &optimizationType);
+template<> ScalingOptimizationType fromInternalString<ScalingOptimizationType>(const QString &strOptimizationType);
 template<> QString toInternalString(const HiDPIOptimizationType &optimizationType);
 template<> HiDPIOptimizationType fromInternalString<HiDPIOptimizationType>(const QString &strOptimizationType);
 #ifndef Q_WS_MAC
@@ -203,6 +203,7 @@ template<> QString toString(const KNetworkAttachmentType &type);
 template<> QString toString(const KNetworkAdapterType &type);
 template<> QString toString(const KNetworkAdapterPromiscModePolicy &policy);
 template<> QString toString(const KPortMode &mode);
+template<> QString toString(const KUSBControllerType &type);
 template<> QString toString(const KUSBDeviceState &state);
 template<> QString toString(const KUSBDeviceFilterAction &action);
 template<> QString toString(const KAudioDriverType &type);
diff --git a/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendCOM.cpp b/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendCOM.cpp
index 601bf4e..40bbaa6 100644
--- a/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendCOM.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendCOM.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2012-2014 Oracle Corporation
+ * Copyright (C) 2012-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -48,6 +48,7 @@ template<> bool canConvert<KNetworkAttachmentType>() { return true; }
 template<> bool canConvert<KNetworkAdapterType>() { return true; }
 template<> bool canConvert<KNetworkAdapterPromiscModePolicy>() { return true; }
 template<> bool canConvert<KPortMode>() { return true; }
+template<> bool canConvert<KUSBControllerType>() { return true; }
 template<> bool canConvert<KUSBDeviceState>() { return true; }
 template<> bool canConvert<KUSBDeviceFilterAction>() { return true; }
 template<> bool canConvert<KAudioDriverType>() { return true; }
@@ -71,6 +72,8 @@ template<> QColor toColor(const KMachineState &state)
         case KMachineState_Paused:                 return QColor(Qt::darkGreen);
         case KMachineState_Stuck:                  return QColor(Qt::darkMagenta);
         case KMachineState_Teleporting:            return QColor(Qt::blue);
+        case KMachineState_Snapshotting:           return QColor(Qt::green);
+        case KMachineState_OnlineSnapshotting:     return QColor(Qt::green);
         case KMachineState_LiveSnapshotting:       return QColor(Qt::green);
         case KMachineState_Starting:               return QColor(Qt::green);
         case KMachineState_Stopping:               return QColor(Qt::green);
@@ -106,6 +109,8 @@ template<> QIcon toIcon(const KMachineState &state)
         case KMachineState_Paused:                 return UIIconPool::iconSet(":/state_paused_16px.png");
         case KMachineState_Stuck:                  return UIIconPool::iconSet(":/state_stuck_16px.png");
         case KMachineState_Teleporting:            return UIIconPool::iconSet(":/state_running_16px.png");
+        case KMachineState_Snapshotting:           return UIIconPool::iconSet(":/state_saving_16px.png");
+        case KMachineState_OnlineSnapshotting:     return UIIconPool::iconSet(":/state_running_16px.png");
         case KMachineState_LiveSnapshotting:       return UIIconPool::iconSet(":/state_running_16px.png");
         case KMachineState_Starting:               return UIIconPool::iconSet(":/state_running_16px.png");
         case KMachineState_Stopping:               return UIIconPool::iconSet(":/state_running_16px.png");
@@ -141,6 +146,8 @@ template<> QString toString(const KMachineState &state)
         case KMachineState_Paused:                 return QApplication::translate("VBoxGlobal", "Paused", "MachineState");
         case KMachineState_Stuck:                  return QApplication::translate("VBoxGlobal", "Guru Meditation", "MachineState");
         case KMachineState_Teleporting:            return QApplication::translate("VBoxGlobal", "Teleporting", "MachineState");
+        case KMachineState_Snapshotting:           return QApplication::translate("VBoxGlobal", "Taking Snapshot", "MachineState");
+        case KMachineState_OnlineSnapshotting:     return QApplication::translate("VBoxGlobal", "Taking Online Snapshot", "MachineState");
         case KMachineState_LiveSnapshotting:       return QApplication::translate("VBoxGlobal", "Taking Live Snapshot", "MachineState");
         case KMachineState_Starting:               return QApplication::translate("VBoxGlobal", "Starting", "MachineState");
         case KMachineState_Stopping:               return QApplication::translate("VBoxGlobal", "Stopping", "MachineState");
@@ -364,11 +371,25 @@ template<> QString toString(const KPortMode &mode)
         case KPortMode_HostPipe:     return QApplication::translate("VBoxGlobal", "Host Pipe", "PortMode");
         case KPortMode_HostDevice:   return QApplication::translate("VBoxGlobal", "Host Device", "PortMode");
         case KPortMode_RawFile:      return QApplication::translate("VBoxGlobal", "Raw File", "PortMode");
+        case KPortMode_TCP:          return QApplication::translate("VBoxGlobal", "TCP", "PortMode");
         AssertMsgFailed(("No text for %d", mode)); break;
     }
     return QString();
 }
 
+/* QString <= KUSBControllerType: */
+template<> QString toString(const KUSBControllerType &type)
+{
+    switch (type)
+    {
+        case KUSBControllerType_OHCI: return QApplication::translate("VBoxGlobal", "OHCI", "USBControllerType");
+        case KUSBControllerType_EHCI: return QApplication::translate("VBoxGlobal", "EHCI", "USBControllerType");
+        case KUSBControllerType_XHCI: return QApplication::translate("VBoxGlobal", "xHCI", "USBControllerType");
+        AssertMsgFailed(("No text for %d", type)); break;
+    }
+    return QString();
+}
+
 /* QString <= KUSBDeviceState: */
 template<> QString toString(const KUSBDeviceState &state)
 {
@@ -543,6 +564,7 @@ template<> KPortMode fromString<KPortMode>(const QString &strMode)
     list.insert(QApplication::translate("VBoxGlobal", "Host Pipe", "PortMode"),    KPortMode_HostPipe);
     list.insert(QApplication::translate("VBoxGlobal", "Host Device", "PortMode"),  KPortMode_HostDevice);
     list.insert(QApplication::translate("VBoxGlobal", "Raw File", "PortMode"),     KPortMode_RawFile);
+    list.insert(QApplication::translate("VBoxGlobal", "TCP", "PortMode"),          KPortMode_TCP);
     if (!list.contains(strMode))
     {
         AssertMsgFailed(("No value for '%s'", strMode.toAscii().constData()));
diff --git a/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp b/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp
index 9bfb3e5..441f9cd 100644
--- a/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp
@@ -39,9 +39,7 @@
 template<> bool canConvert<SizeSuffix>() { return true; }
 template<> bool canConvert<StorageSlot>() { return true; }
 template<> bool canConvert<UIExtraDataMetaDefs::MenuType>() { return true; }
-#ifdef Q_WS_MAC
 template<> bool canConvert<UIExtraDataMetaDefs::MenuApplicationActionType>() { return true; }
-#endif /* Q_WS_MAC */
 template<> bool canConvert<UIExtraDataMetaDefs::MenuHelpActionType>() { return true; }
 template<> bool canConvert<UIExtraDataMetaDefs::RuntimeMenuMachineActionType>() { return true; }
 template<> bool canConvert<UIExtraDataMetaDefs::RuntimeMenuViewActionType>() { return true; }
@@ -63,6 +61,7 @@ template<> bool canConvert<IndicatorType>() { return true; }
 template<> bool canConvert<MachineCloseAction>() { return true; }
 template<> bool canConvert<MouseCapturePolicy>() { return true; }
 template<> bool canConvert<GuruMeditationHandlerType>() { return true; }
+template<> bool canConvert<ScalingOptimizationType>() { return true; }
 template<> bool canConvert<HiDPIOptimizationType>() { return true; }
 #ifndef Q_WS_MAC
 template<> bool canConvert<MiniToolbarAlignment>() { return true; }
@@ -373,9 +372,7 @@ template<> QString toInternalString(const UIExtraDataMetaDefs::MenuType &menuTyp
     QString strResult;
     switch (menuType)
     {
-#ifdef RT_OS_DARWIN
         case UIExtraDataMetaDefs::MenuType_Application: strResult = "Application"; break;
-#endif /* RT_OS_DARWIN */
         case UIExtraDataMetaDefs::MenuType_Machine:     strResult = "Machine"; break;
         case UIExtraDataMetaDefs::MenuType_View:        strResult = "View"; break;
         case UIExtraDataMetaDefs::MenuType_Input:       strResult = "Input"; break;
@@ -403,9 +400,7 @@ template<> UIExtraDataMetaDefs::MenuType fromInternalString<UIExtraDataMetaDefs:
     /* Here we have some fancy stuff allowing us
      * to search through the keys using 'case-insensitive' rule: */
     QStringList keys;      QList<UIExtraDataMetaDefs::MenuType> values;
-#ifdef RT_OS_DARWIN
     keys << "Application"; values << UIExtraDataMetaDefs::MenuType_Application;
-#endif /* RT_OS_DARWIN */
     keys << "Machine";     values << UIExtraDataMetaDefs::MenuType_Machine;
     keys << "View";        values << UIExtraDataMetaDefs::MenuType_View;
     keys << "Input";       values << UIExtraDataMetaDefs::MenuType_Input;
@@ -425,17 +420,23 @@ template<> UIExtraDataMetaDefs::MenuType fromInternalString<UIExtraDataMetaDefs:
     return values.at(keys.indexOf(QRegExp(strMenuType, Qt::CaseInsensitive)));
 }
 
-#ifdef Q_WS_MAC
 /* QString <= UIExtraDataMetaDefs::MenuApplicationActionType: */
 template<> QString toInternalString(const UIExtraDataMetaDefs::MenuApplicationActionType &menuApplicationActionType)
 {
     QString strResult;
     switch (menuApplicationActionType)
     {
-        case UIExtraDataMetaDefs::MenuApplicationActionType_About:       strResult = "About"; break;
-        case UIExtraDataMetaDefs::MenuApplicationActionType_Preferences: strResult = "Preferences"; break;
-        case UIExtraDataMetaDefs::MenuApplicationActionType_Close:       strResult = "Close"; break;
-        case UIExtraDataMetaDefs::MenuApplicationActionType_All:         strResult = "All"; break;
+#ifdef Q_WS_MAC
+        case UIExtraDataMetaDefs::MenuApplicationActionType_About:                strResult = "About"; break;
+#endif /* Q_WS_MAC */
+        case UIExtraDataMetaDefs::MenuApplicationActionType_Preferences:          strResult = "Preferences"; break;
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+        case UIExtraDataMetaDefs::MenuApplicationActionType_NetworkAccessManager: strResult = "NetworkAccessManager"; break;
+        case UIExtraDataMetaDefs::MenuApplicationActionType_CheckForUpdates:      strResult = "CheckForUpdates"; break;
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+        case UIExtraDataMetaDefs::MenuApplicationActionType_ResetWarnings:        strResult = "ResetWarnings"; break;
+        case UIExtraDataMetaDefs::MenuApplicationActionType_Close:                strResult = "Close"; break;
+        case UIExtraDataMetaDefs::MenuApplicationActionType_All:                  strResult = "All"; break;
         default:
         {
             AssertMsgFailed(("No text for action type=%d", menuApplicationActionType));
@@ -450,18 +451,24 @@ template<> UIExtraDataMetaDefs::MenuApplicationActionType fromInternalString<UIE
 {
     /* Here we have some fancy stuff allowing us
      * to search through the keys using 'case-insensitive' rule: */
-    QStringList keys;      QList<UIExtraDataMetaDefs::MenuApplicationActionType> values;
-    keys << "About";       values << UIExtraDataMetaDefs::MenuApplicationActionType_About;
-    keys << "Preferences"; values << UIExtraDataMetaDefs::MenuApplicationActionType_Preferences;
-    keys << "Close";       values << UIExtraDataMetaDefs::MenuApplicationActionType_Close;
-    keys << "All";         values << UIExtraDataMetaDefs::MenuApplicationActionType_All;
+    QStringList keys;               QList<UIExtraDataMetaDefs::MenuApplicationActionType> values;
+#ifdef Q_WS_MAC
+    keys << "About";                values << UIExtraDataMetaDefs::MenuApplicationActionType_About;
+#endif /* Q_WS_MAC */
+    keys << "Preferences";          values << UIExtraDataMetaDefs::MenuApplicationActionType_Preferences;
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+    keys << "NetworkAccessManager"; values << UIExtraDataMetaDefs::MenuApplicationActionType_NetworkAccessManager;
+    keys << "CheckForUpdates";      values << UIExtraDataMetaDefs::MenuApplicationActionType_CheckForUpdates;
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+    keys << "ResetWarnings";        values << UIExtraDataMetaDefs::MenuApplicationActionType_ResetWarnings;
+    keys << "Close";                values << UIExtraDataMetaDefs::MenuApplicationActionType_Close;
+    keys << "All";                  values << UIExtraDataMetaDefs::MenuApplicationActionType_All;
     /* Invalid type for unknown words: */
     if (!keys.contains(strMenuApplicationActionType, Qt::CaseInsensitive))
         return UIExtraDataMetaDefs::MenuApplicationActionType_Invalid;
     /* Corresponding type for known words: */
     return values.at(keys.indexOf(QRegExp(strMenuApplicationActionType, Qt::CaseInsensitive)));
 }
-#endif /* Q_WS_MAC */
 
 /* QString <= UIExtraDataMetaDefs::MenuHelpActionType: */
 template<> QString toInternalString(const UIExtraDataMetaDefs::MenuHelpActionType &menuHelpActionType)
@@ -471,14 +478,8 @@ template<> QString toInternalString(const UIExtraDataMetaDefs::MenuHelpActionTyp
     {
         case UIExtraDataMetaDefs::MenuHelpActionType_Contents:             strResult = "Contents"; break;
         case UIExtraDataMetaDefs::MenuHelpActionType_WebSite:              strResult = "WebSite"; break;
-        case UIExtraDataMetaDefs::MenuHelpActionType_ResetWarnings:        strResult = "ResetWarnings"; break;
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-        case UIExtraDataMetaDefs::MenuHelpActionType_NetworkAccessManager: strResult = "NetworkAccessManager"; break;
-        case UIExtraDataMetaDefs::MenuHelpActionType_CheckForUpdates:      strResult = "CheckForUpdates"; break;
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
 #ifndef Q_WS_MAC
         case UIExtraDataMetaDefs::MenuHelpActionType_About:                strResult = "About"; break;
-        case UIExtraDataMetaDefs::MenuHelpActionType_Preferences:          strResult = "Preferences"; break;
 #endif /* !Q_WS_MAC */
         case UIExtraDataMetaDefs::MenuHelpActionType_All:                  strResult = "All"; break;
         default:
@@ -498,14 +499,8 @@ template<> UIExtraDataMetaDefs::MenuHelpActionType fromInternalString<UIExtraDat
     QStringList keys;               QList<UIExtraDataMetaDefs::MenuHelpActionType> values;
     keys << "Contents";             values << UIExtraDataMetaDefs::MenuHelpActionType_Contents;
     keys << "WebSite";              values << UIExtraDataMetaDefs::MenuHelpActionType_WebSite;
-    keys << "ResetWarnings";        values << UIExtraDataMetaDefs::MenuHelpActionType_ResetWarnings;
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-    keys << "NetworkAccessManager"; values << UIExtraDataMetaDefs::MenuHelpActionType_NetworkAccessManager;
-    keys << "CheckForUpdates";      values << UIExtraDataMetaDefs::MenuHelpActionType_CheckForUpdates;
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
 #ifndef Q_WS_MAC
     keys << "About";                values << UIExtraDataMetaDefs::MenuHelpActionType_About;
-    keys << "Preferences";          values << UIExtraDataMetaDefs::MenuHelpActionType_Preferences;
 #endif /* !Q_WS_MAC */
     keys << "All";                  values << UIExtraDataMetaDefs::MenuHelpActionType_All;
     /* Invalid type for unknown words: */
@@ -529,9 +524,6 @@ template<> QString toInternalString(const UIExtraDataMetaDefs::RuntimeMenuMachin
         case UIExtraDataMetaDefs::RuntimeMenuMachineActionType_SaveState:         strResult = "SaveState"; break;
         case UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Shutdown:          strResult = "Shutdown"; break;
         case UIExtraDataMetaDefs::RuntimeMenuMachineActionType_PowerOff:          strResult = "PowerOff"; break;
-#ifndef Q_WS_MAC
-        case UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Close:             strResult = "Close"; break;
-#endif /* !Q_WS_MAC */
         case UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Nothing:           strResult = "Nothing"; break;
         case UIExtraDataMetaDefs::RuntimeMenuMachineActionType_All:               strResult = "All"; break;
         default:
@@ -557,9 +549,6 @@ template<> UIExtraDataMetaDefs::RuntimeMenuMachineActionType fromInternalString<
     keys << "SaveState";         values << UIExtraDataMetaDefs::RuntimeMenuMachineActionType_SaveState;
     keys << "Shutdown";          values << UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Shutdown;
     keys << "PowerOff";          values << UIExtraDataMetaDefs::RuntimeMenuMachineActionType_PowerOff;
-#ifndef Q_WS_MAC
-    keys << "Close";             values << UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Close;
-#endif /* !Q_WS_MAC */
     keys << "Nothing";           values << UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Nothing;
     keys << "All";               values << UIExtraDataMetaDefs::RuntimeMenuMachineActionType_All;
     /* Invalid type for unknown words: */
@@ -1422,6 +1411,38 @@ template<> GuruMeditationHandlerType fromInternalString<GuruMeditationHandlerTyp
     return values.at(keys.indexOf(QRegExp(strGuruMeditationHandlerType, Qt::CaseInsensitive)));
 }
 
+/* QString <= ScalingOptimizationType: */
+template<> QString toInternalString(const ScalingOptimizationType &optimizationType)
+{
+    QString strResult;
+    switch (optimizationType)
+    {
+        case ScalingOptimizationType_None:        strResult = "None"; break;
+        case ScalingOptimizationType_Performance: strResult = "Performance"; break;
+        default:
+        {
+            AssertMsgFailed(("No text for type=%d", optimizationType));
+            break;
+        }
+    }
+    return strResult;
+}
+
+/* ScalingOptimizationType <= QString: */
+template<> ScalingOptimizationType fromInternalString<ScalingOptimizationType>(const QString &strOptimizationType)
+{
+    /* Here we have some fancy stuff allowing us
+     * to search through the keys using 'case-insensitive' rule: */
+    QStringList keys;      QList<ScalingOptimizationType> values;
+    keys << "None";        values << ScalingOptimizationType_None;
+    keys << "Performance"; values << ScalingOptimizationType_Performance;
+    /* 'None' type for empty/unknown words: */
+    if (!keys.contains(strOptimizationType, Qt::CaseInsensitive))
+        return ScalingOptimizationType_None;
+    /* Corresponding type for known words: */
+    return values.at(keys.indexOf(QRegExp(strOptimizationType, Qt::CaseInsensitive)));
+}
+
 /* QString <= HiDPIOptimizationType: */
 template<> QString toInternalString(const HiDPIOptimizationType &optimizationType)
 {
diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIStyledItemDelegate.h b/src/VBox/Frontends/VirtualBox/src/extensions/QIStyledItemDelegate.h
index db65437..cf45774 100644
--- a/src/VBox/Frontends/VirtualBox/src/extensions/QIStyledItemDelegate.h
+++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIStyledItemDelegate.h
@@ -27,23 +27,41 @@ class QIStyledItemDelegate : public QStyledItemDelegate
 {
     Q_OBJECT;
 
+signals:
+
+    /** Notifies listeners about
+      * created editor's Enter/Return key triggering. */
+    void sigEditorEnterKeyTriggered();
+
 public:
 
     /** Constructor. */
-    QIStyledItemDelegate(QObject *pParent) : QStyledItemDelegate(pParent) {}
+    QIStyledItemDelegate(QObject *pParent)
+        : QStyledItemDelegate(pParent)
+        , m_fWatchForEditorEnterKeyTriggering(false)
+    {}
+
+    /** Defines whether QIStyledItemDelegate should watch for the created editor's Enter/Return key triggering. */
+    void setWatchForEditorEnterKeyTriggering(bool fWatch) { m_fWatchForEditorEnterKeyTriggering = fWatch; }
 
 private:
 
     /** Returns the widget used to edit the item specified by @a index for editing.
       * The @a pParent widget and style @a option are used to control how the editor widget appears.
-      * Besides Qt description copy-pasted above we are installing the hook to redirect editor's sigCommitData signal. */
+      * Besides that, we are installing the hooks to redirect editor's sigCommitData and sigEnterKeyTriggered signals. */
     QWidget* createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const
     {
         /* Call to base-class to get actual editor created: */
         QWidget *pEditor = QStyledItemDelegate::createEditor(pParent, option, index);
-        /* All the stuff we actually need from QIStyledItemDelegate is to redirect this one signal: */
+        /* All the stuff we actually need from QIStyledItemDelegate is to redirect these signals: */
         connect(pEditor, SIGNAL(sigCommitData(QWidget*)), this, SIGNAL(commitData(QWidget*)));
+        if (m_fWatchForEditorEnterKeyTriggering)
+            connect(pEditor, SIGNAL(sigEnterKeyTriggered()), this, SIGNAL(sigEditorEnterKeyTriggered()));
         /* Return actual editor: */
         return pEditor;
     }
+
+    /** Holds whether QIStyledItemDelegate should watch
+      * for the created editor's Enter/Return key triggering. */
+    bool m_fWatchForEditorEnterKeyTriggering;
 };
diff --git a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.cpp b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.cpp
index c546392..5b34d37 100644
--- a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.cpp
@@ -91,9 +91,7 @@ const char* UIExtraDataDefs::GUI_Geometry_State_Max = "max";
 const char* UIExtraDataDefs::GUI_MenuBar_Enabled = "GUI/MenuBar/Enabled";
 #endif /* !Q_WS_MAC */
 const char* UIExtraDataDefs::GUI_RestrictedRuntimeMenus = "GUI/RestrictedRuntimeMenus";
-#ifdef Q_WS_MAC
 const char* UIExtraDataDefs::GUI_RestrictedRuntimeApplicationMenuActions = "GUI/RestrictedRuntimeApplicationMenuActions";
-#endif /* Q_WS_MAC */
 const char* UIExtraDataDefs::GUI_RestrictedRuntimeMachineMenuActions = "GUI/RestrictedRuntimeMachineMenuActions";
 const char* UIExtraDataDefs::GUI_RestrictedRuntimeViewMenuActions = "GUI/RestrictedRuntimeViewMenuActions";
 const char* UIExtraDataDefs::GUI_RestrictedRuntimeInputMenuActions = "GUI/RestrictedRuntimeInputMenuActions";
@@ -144,6 +142,7 @@ const char* UIExtraDataDefs::GUI_MouseCapturePolicy = "GUI/MouseCapturePolicy";
 const char* UIExtraDataDefs::GUI_GuruMeditationHandler = "GUI/GuruMeditationHandler";
 const char* UIExtraDataDefs::GUI_HidLedsSync = "GUI/HidLedsSync";
 const char* UIExtraDataDefs::GUI_ScaleFactor = "GUI/ScaleFactor";
+const char* UIExtraDataDefs::GUI_Scaling_Optimization = "GUI/Scaling/Optimization";
 
 /* Virtual Machine: Information dialog: */
 const char* UIExtraDataDefs::GUI_InformationWindowGeometry = "GUI/InformationWindowGeometry";
diff --git a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h
index 0671013..4d0ba66 100644
--- a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h
+++ b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h
@@ -153,10 +153,8 @@ namespace UIExtraDataDefs
 #endif /* !Q_WS_MAC */
         /** Holds restricted Runtime UI menu types. */
         extern const char* GUI_RestrictedRuntimeMenus;
-#ifdef Q_WS_MAC
-        /** Mac OS X: Holds restricted Runtime UI action types for 'Application' menu. */
+        /** Holds restricted Runtime UI action types for 'Application' menu. */
         extern const char* GUI_RestrictedRuntimeApplicationMenuActions;
-#endif /* Q_WS_MAC */
         /** Holds restricted Runtime UI action types for Machine menu. */
         extern const char* GUI_RestrictedRuntimeMachineMenuActions;
         /** Holds restricted Runtime UI action types for View menu. */
@@ -248,6 +246,8 @@ namespace UIExtraDataDefs
         extern const char* GUI_HidLedsSync;
         /** Holds the scale-factor. */
         extern const char* GUI_ScaleFactor;
+        /** Holds the scaling optimization type. */
+        extern const char* GUI_Scaling_Optimization;
     /** @} */
 
     /** @name Virtual Machine: Information dialog
@@ -294,9 +294,7 @@ class UIExtraDataMetaDefs : public QObject
 {
     Q_OBJECT;
     Q_ENUMS(MenuType);
-#ifdef RT_OS_DARWIN
     Q_ENUMS(MenuApplicationActionType);
-#endif /* RT_OS_DARWIN */
     Q_ENUMS(MenuHelpActionType);
     Q_ENUMS(RuntimeMenuMachineActionType);
     Q_ENUMS(RuntimeMenuViewActionType);
@@ -315,9 +313,7 @@ public:
     enum MenuType
     {
         MenuType_Invalid     = 0,
-#ifdef RT_OS_DARWIN
         MenuType_Application = RT_BIT(0),
-#endif /* RT_OS_DARWIN */
         MenuType_Machine     = RT_BIT(1),
         MenuType_View        = RT_BIT(2),
         MenuType_Input       = RT_BIT(3),
@@ -332,17 +328,22 @@ public:
         MenuType_All         = 0xFF
     };
 
-#ifdef RT_OS_DARWIN
     /** Menu "Application": Action types. */
     enum MenuApplicationActionType
     {
-        MenuApplicationActionType_Invalid     = 0,
-        MenuApplicationActionType_About       = RT_BIT(0),
-        MenuApplicationActionType_Preferences = RT_BIT(1),
-        MenuApplicationActionType_Close       = RT_BIT(2),
-        MenuApplicationActionType_All         = 0xFFFF
-    };
+        MenuApplicationActionType_Invalid              = 0,
+#ifdef RT_OS_DARWIN
+        MenuApplicationActionType_About                = RT_BIT(0),
 #endif /* RT_OS_DARWIN */
+        MenuApplicationActionType_Preferences          = RT_BIT(1),
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+        MenuApplicationActionType_NetworkAccessManager = RT_BIT(2),
+        MenuApplicationActionType_CheckForUpdates      = RT_BIT(3),
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+        MenuApplicationActionType_ResetWarnings        = RT_BIT(4),
+        MenuApplicationActionType_Close                = RT_BIT(5),
+        MenuApplicationActionType_All                  = 0xFFFF
+    };
 
     /** Menu "Help": Action types. */
     enum MenuHelpActionType
@@ -350,14 +351,8 @@ public:
         MenuHelpActionType_Invalid              = 0,
         MenuHelpActionType_Contents             = RT_BIT(0),
         MenuHelpActionType_WebSite              = RT_BIT(1),
-        MenuHelpActionType_ResetWarnings        = RT_BIT(2),
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-        MenuHelpActionType_NetworkAccessManager = RT_BIT(3),
-        MenuHelpActionType_CheckForUpdates      = RT_BIT(4),
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
 #ifndef RT_OS_DARWIN
-        MenuHelpActionType_About                = RT_BIT(5),
-        MenuHelpActionType_Preferences          = RT_BIT(6),
+        MenuHelpActionType_About                = RT_BIT(2),
 #endif /* !RT_OS_DARWIN */
         MenuHelpActionType_All                  = 0xFFFF
     };
@@ -374,10 +369,7 @@ public:
         RuntimeMenuMachineActionType_SaveState         = RT_BIT(5),
         RuntimeMenuMachineActionType_Shutdown          = RT_BIT(6),
         RuntimeMenuMachineActionType_PowerOff          = RT_BIT(7),
-#ifndef RT_OS_DARWIN
-        RuntimeMenuMachineActionType_Close             = RT_BIT(8),
-#endif /* !RT_OS_DARWIN */
-        RuntimeMenuMachineActionType_Nothing           = RT_BIT(9),
+        RuntimeMenuMachineActionType_Nothing           = RT_BIT(8),
         RuntimeMenuMachineActionType_All               = 0xFFFF
     };
 
@@ -631,6 +623,13 @@ enum GuruMeditationHandlerType
     GuruMeditationHandlerType_Ignore
 };
 
+/** Runtime UI: Scaling optimization types. */
+enum ScalingOptimizationType
+{
+    ScalingOptimizationType_None,
+    ScalingOptimizationType_Performance
+};
+
 /** Runtime UI: HiDPI optimization types. */
 enum HiDPIOptimizationType
 {
diff --git a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.cpp b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.cpp
index 89099e7..f2613a9 100644
--- a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.cpp
@@ -1757,9 +1757,7 @@ QStringList UIExtraDataManagerWindow::knownExtraDataKeys()
 #endif /* !Q_WS_MAC */
            << GUI_LastNormalWindowPosition << GUI_LastScaleWindowPosition
            << GUI_RestrictedRuntimeMenus
-#ifdef Q_WS_MAC
            << GUI_RestrictedRuntimeApplicationMenuActions
-#endif /* Q_WS_MAC */
            << GUI_RestrictedRuntimeMachineMenuActions
            << GUI_RestrictedRuntimeViewMenuActions
            << GUI_RestrictedRuntimeInputMenuActions
@@ -1797,7 +1795,7 @@ QStringList UIExtraDataManagerWindow::knownExtraDataKeys()
            << GUI_MouseCapturePolicy
            << GUI_GuruMeditationHandler
            << GUI_HidLedsSync
-           << GUI_ScaleFactor
+           << GUI_ScaleFactor << GUI_Scaling_Optimization
            << GUI_InformationWindowGeometry
            << GUI_DefaultCloseAction << GUI_RestrictedCloseActions
            << GUI_LastCloseAction << GUI_CloseActionHook
@@ -2611,7 +2609,6 @@ void UIExtraDataManager::setRestrictedRuntimeMenuTypes(UIExtraDataMetaDefs::Menu
     setExtraDataStringList(GUI_RestrictedRuntimeMenus, result, strID);
 }
 
-#ifdef Q_WS_MAC
 UIExtraDataMetaDefs::MenuApplicationActionType UIExtraDataManager::restrictedRuntimeMenuApplicationActionTypes(const QString &strID)
 {
     /* Prepare result: */
@@ -2658,7 +2655,6 @@ void UIExtraDataManager::setRestrictedRuntimeMenuApplicationActionTypes(UIExtraD
     /* Save result: */
     setExtraDataStringList(GUI_RestrictedRuntimeApplicationMenuActions, result, strID);
 }
-#endif /* Q_WS_MAC */
 
 UIExtraDataMetaDefs::RuntimeMenuMachineActionType UIExtraDataManager::restrictedRuntimeMenuMachineActionTypes(const QString &strID)
 {
@@ -3395,6 +3391,11 @@ void UIExtraDataManager::setScaleFactor(double dScaleFactor, const QString &strI
     setExtraDataString(GUI_ScaleFactor, QString::number(dScaleFactor), strID);
 }
 
+ScalingOptimizationType UIExtraDataManager::scalingOptimizationType(const QString &strID)
+{
+    return gpConverter->fromInternalString<ScalingOptimizationType>(extraDataString(GUI_Scaling_Optimization, strID));
+}
+
 QRect UIExtraDataManager::informationWindowGeometry(QWidget *pWidget, QWidget *pParentWidget, const QString &strID)
 {
     /* Get corresponding extra-data: */
@@ -3674,9 +3675,7 @@ void UIExtraDataManager::sltExtraDataChange(QString strMachineID, QString strKey
             strKey == GUI_MenuBar_Enabled ||
 #endif /* !Q_WS_MAC */
             strKey == GUI_RestrictedRuntimeMenus ||
-#ifdef Q_WS_MAC
             strKey == GUI_RestrictedRuntimeApplicationMenuActions ||
-#endif /* Q_WS_MAC */
             strKey == GUI_RestrictedRuntimeMachineMenuActions ||
             strKey == GUI_RestrictedRuntimeViewMenuActions ||
             strKey == GUI_RestrictedRuntimeInputMenuActions ||
@@ -3697,6 +3696,10 @@ void UIExtraDataManager::sltExtraDataChange(QString strMachineID, QString strKey
         /* Scale-factor change: */
         else if (strKey == GUI_ScaleFactor)
             emit sigScaleFactorChange(strMachineID);
+        /* Scaling optimization type change: */
+        else if (strKey == GUI_Scaling_Optimization)
+            emit sigScalingOptimizationTypeChange(strMachineID);
+        /* Unscaled HiDPI Output mode change: */
         else if (strKey == GUI_HiDPI_UnscaledOutput)
             emit sigUnscaledHiDPIOutputModeChange(strMachineID);
     }
diff --git a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.h b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.h
index da2a88e..eae3b55 100644
--- a/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.h
+++ b/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.h
@@ -78,6 +78,9 @@ signals:
     /** Notifies about the scale-factor change. */
     void sigScaleFactorChange(const QString &strMachineID);
 
+    /** Notifies about the scaling optimization type change. */
+    void sigScalingOptimizationTypeChange(const QString &strMachineID);
+
     /** Notifies about unscaled HiDPI output mode change. */
     void sigUnscaledHiDPIOutputModeChange(const QString &strMachineID);
 
@@ -311,12 +314,10 @@ public:
         /** Defines restricted Runtime UI menu types. */
         void setRestrictedRuntimeMenuTypes(UIExtraDataMetaDefs::MenuType types, const QString &strID);
 
-#ifdef Q_WS_MAC
-        /** Mac OS X: Returns restricted Runtime UI action types for Application menu. */
+        /** Returns restricted Runtime UI action types for Application menu. */
         UIExtraDataMetaDefs::MenuApplicationActionType restrictedRuntimeMenuApplicationActionTypes(const QString &strID);
-        /** Mac OS X: Defines restricted Runtime UI action types for Application menu. */
+        /** Defines restricted Runtime UI action types for Application menu. */
         void setRestrictedRuntimeMenuApplicationActionTypes(UIExtraDataMetaDefs::MenuApplicationActionType types, const QString &strID);
-#endif /* Q_WS_MAC */
 
         /** Returns restricted Runtime UI action types for Machine menu. */
         UIExtraDataMetaDefs::RuntimeMenuMachineActionType restrictedRuntimeMenuMachineActionTypes(const QString &strID);
@@ -476,6 +477,9 @@ public:
         double scaleFactor(const QString &strID);
         /** Defines the @a dScaleFactor. */
         void setScaleFactor(double dScaleFactor, const QString &strID);
+
+        /** Returns the scaling optimization type. */
+        ScalingOptimizationType scalingOptimizationType(const QString &strID);
     /** @} */
 
     /** @name Virtual Machine: Information dialog
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.cpp
index 08e0282..81dc241 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.cpp
@@ -315,7 +315,6 @@ UIActionPolymorphic::UIActionPolymorphic(UIActionPool *pParent,
 }
 
 
-#ifdef RT_OS_DARWIN
 class UIActionMenuApplication : public UIActionMenu
 {
     Q_OBJECT;
@@ -325,7 +324,9 @@ public:
     UIActionMenuApplication(UIActionPool *pParent)
         : UIActionMenu(pParent)
     {
+#ifdef RT_OS_DARWIN
         menu()->setConsumable(true);
+#endif /* RT_OS_DARWIN */
         retranslateUi();
     }
 
@@ -340,7 +341,11 @@ protected:
 
     void retranslateUi()
     {
+#ifdef RT_OS_DARWIN
         setName(QApplication::translate("UIActionPool", "&VirtualBox"));
+#else /* !RT_OS_DARWIN */
+        setName(QApplication::translate("UIActionPool", "&File"));
+#endif /* !RT_OS_DARWIN */
     }
 };
 
@@ -382,6 +387,7 @@ protected:
     }
 };
 
+#ifdef RT_OS_DARWIN
 class UIActionMenuWindow : public UIActionMenu
 {
     Q_OBJECT;
@@ -549,17 +555,18 @@ public:
     UIActionSimpleResetWarnings(UIActionPool *pParent)
         : UIActionSimple(pParent, ":/reset_warnings_16px.png")
     {
+        setMenuRole(QAction::ApplicationSpecificRole);
         retranslateUi();
     }
 
 protected:
 
     /** Returns action extra-data ID. */
-    virtual int extraDataID() const { return UIExtraDataMetaDefs::MenuHelpActionType_ResetWarnings; }
+    virtual int extraDataID() const { return UIExtraDataMetaDefs::MenuApplicationActionType_ResetWarnings; }
     /** Returns action extra-data key. */
-    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuHelpActionType_ResetWarnings); }
+    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuApplicationActionType_ResetWarnings); }
     /** Returns whether action is allowed. */
-    virtual bool isAllowed() const { return actionPool()->isAllowedInMenuHelp(UIExtraDataMetaDefs::MenuHelpActionType_ResetWarnings); }
+    virtual bool isAllowed() const { return actionPool()->isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType_ResetWarnings); }
 
     QString shortcutExtraDataID() const
     {
@@ -583,17 +590,18 @@ public:
     UIActionSimpleNetworkAccessManager(UIActionPool *pParent)
         : UIActionSimple(pParent, ":/nw_16px.png", ":/nw_disabled_16px.png")
     {
+        setMenuRole(QAction::ApplicationSpecificRole);
         retranslateUi();
     }
 
 protected:
 
     /** Returns action extra-data ID. */
-    virtual int extraDataID() const { return UIExtraDataMetaDefs::MenuHelpActionType_NetworkAccessManager; }
+    virtual int extraDataID() const { return UIExtraDataMetaDefs::MenuApplicationActionType_NetworkAccessManager; }
     /** Returns action extra-data key. */
-    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuHelpActionType_NetworkAccessManager); }
+    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuApplicationActionType_NetworkAccessManager); }
     /** Returns whether action is allowed. */
-    virtual bool isAllowed() const { return actionPool()->isAllowedInMenuHelp(UIExtraDataMetaDefs::MenuHelpActionType_NetworkAccessManager); }
+    virtual bool isAllowed() const { return actionPool()->isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType_NetworkAccessManager); }
 
     QString shortcutExtraDataID() const
     {
@@ -623,11 +631,11 @@ public:
 protected:
 
     /** Returns action extra-data ID. */
-    virtual int extraDataID() const { return UIExtraDataMetaDefs::MenuHelpActionType_CheckForUpdates; }
+    virtual int extraDataID() const { return UIExtraDataMetaDefs::MenuApplicationActionType_CheckForUpdates; }
     /** Returns action extra-data key. */
-    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuHelpActionType_CheckForUpdates); }
+    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuApplicationActionType_CheckForUpdates); }
     /** Returns whether action is allowed. */
-    virtual bool isAllowed() const { return actionPool()->isAllowedInMenuHelp(UIExtraDataMetaDefs::MenuHelpActionType_CheckForUpdates); }
+    virtual bool isAllowed() const { return actionPool()->isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType_CheckForUpdates); }
 
     QString shortcutExtraDataID() const
     {
@@ -660,29 +668,29 @@ protected:
     /** Returns action extra-data ID. */
     virtual int extraDataID() const
     {
-#ifdef Q_WS_MAC
+#ifdef RT_OS_DARWIN
         return UIExtraDataMetaDefs::MenuApplicationActionType_About;
-#else /* !Q_WS_MAC */
+#else /* !RT_OS_DARWIN */
         return UIExtraDataMetaDefs::MenuHelpActionType_About;
-#endif /* !Q_WS_MAC */
+#endif /* !RT_OS_DARWIN */
     }
     /** Returns action extra-data key. */
     virtual QString extraDataKey() const
     {
-#ifdef Q_WS_MAC
+#ifdef RT_OS_DARWIN
         return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuApplicationActionType_About);
-#else /* !Q_WS_MAC */
+#else /* !RT_OS_DARWIN */
         return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuHelpActionType_About);
-#endif /* !Q_WS_MAC */
+#endif /* !RT_OS_DARWIN */
     }
     /** Returns whether action is allowed. */
     virtual bool isAllowed() const
     {
-#ifdef Q_WS_MAC
+#ifdef RT_OS_DARWIN
         return actionPool()->isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType_About);
-#else /* !Q_WS_MAC */
+#else /* !RT_OS_DARWIN */
         return actionPool()->isAllowedInMenuHelp(UIExtraDataMetaDefs::MenuHelpActionType_About);
-#endif /* !Q_WS_MAC */
+#endif /* !RT_OS_DARWIN */
     }
 
     QString shortcutExtraDataID() const
@@ -713,32 +721,11 @@ public:
 protected:
 
     /** Returns action extra-data ID. */
-    virtual int extraDataID() const
-    {
-#ifdef Q_WS_MAC
-        return UIExtraDataMetaDefs::MenuApplicationActionType_Preferences;
-#else /* !Q_WS_MAC */
-        return UIExtraDataMetaDefs::MenuHelpActionType_Preferences;
-#endif /* !Q_WS_MAC */
-    }
+    virtual int extraDataID() const { return UIExtraDataMetaDefs::MenuApplicationActionType_Preferences; }
     /** Returns action extra-data key. */
-    virtual QString extraDataKey() const
-    {
-#ifdef Q_WS_MAC
-        return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuApplicationActionType_Preferences);
-#else /* !Q_WS_MAC */
-        return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuHelpActionType_Preferences);
-#endif /* !Q_WS_MAC */
-    }
+    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::MenuApplicationActionType_Preferences); }
     /** Returns whether action is allowed. */
-    virtual bool isAllowed() const
-    {
-#ifdef Q_WS_MAC
-        return actionPool()->isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType_Preferences);
-#else /* !Q_WS_MAC */
-        return actionPool()->isAllowedInMenuHelp(UIExtraDataMetaDefs::MenuHelpActionType_Preferences);
-#endif /* !Q_WS_MAC */
-    }
+    virtual bool isAllowed() const { return actionPool()->isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType_Preferences); }
 
     QString shortcutExtraDataID() const
     {
@@ -832,7 +819,6 @@ void UIActionPool::setRestrictionForMenuBar(UIActionRestrictionLevel level, UIEx
     updateMenus();
 }
 
-#ifdef Q_WS_MAC
 bool UIActionPool::isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType type) const
 {
     foreach (const UIExtraDataMetaDefs::MenuApplicationActionType &restriction, m_restrictedActionsMenuApplication.values())
@@ -847,6 +833,7 @@ void UIActionPool::setRestrictionForMenuApplication(UIActionRestrictionLevel lev
     m_invalidations << UIActionIndex_M_Application;
 }
 
+#ifdef Q_WS_MAC
 bool UIActionPool::isAllowedInMenuWindow(UIExtraDataMetaDefs::MenuWindowActionType type) const
 {
     foreach (const UIExtraDataMetaDefs::MenuWindowActionType &restriction, m_restrictedActionsMenuWindow.values())
@@ -909,13 +896,20 @@ void UIActionPool::prepare()
 
 void UIActionPool::preparePool()
 {
-#ifdef RT_OS_DARWIN
     /* Create 'Application' actions: */
     m_pool[UIActionIndex_M_Application] = new UIActionMenuApplication(this);
+#ifdef RT_OS_DARWIN
     m_pool[UIActionIndex_M_Application_S_About] = new UIActionSimpleAbout(this);
+#endif /* RT_OS_DARWIN */
     m_pool[UIActionIndex_M_Application_S_Preferences] = new UIActionSimplePreferences(this);
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+    m_pool[UIActionIndex_M_Application_S_NetworkAccessManager] = new UIActionSimpleNetworkAccessManager(this);
+    m_pool[UIActionIndex_M_Application_S_CheckForUpdates] = new UIActionSimpleCheckForUpdates(this);
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+    m_pool[UIActionIndex_M_Application_S_ResetWarnings] = new UIActionSimpleResetWarnings(this);
     m_pool[UIActionIndex_M_Application_S_Close] = new UIActionSimplePerformClose(this);
 
+#ifdef RT_OS_DARWIN
     /* Create 'Window' actions: */
     m_pool[UIActionIndex_M_Window] = new UIActionMenuWindow(this);
     m_pool[UIActionIndex_M_Window_S_Minimize] = new UIActionSimpleMinimize(this);
@@ -925,14 +919,8 @@ void UIActionPool::preparePool()
     m_pool[UIActionIndex_Menu_Help] = new UIActionMenuHelp(this);
     m_pool[UIActionIndex_Simple_Contents] = new UIActionSimpleContents(this);
     m_pool[UIActionIndex_Simple_WebSite] = new UIActionSimpleWebSite(this);
-    m_pool[UIActionIndex_Simple_ResetWarnings] = new UIActionSimpleResetWarnings(this);
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-    m_pool[UIActionIndex_Simple_NetworkAccessManager] = new UIActionSimpleNetworkAccessManager(this);
-    m_pool[UIActionIndex_Simple_CheckForUpdates] = new UIActionSimpleCheckForUpdates(this);
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
 #ifndef RT_OS_DARWIN
     m_pool[UIActionIndex_Simple_About] = new UIActionSimpleAbout(this);
-    m_pool[UIActionIndex_Simple_Preferences] = new UIActionSimplePreferences(this);
 #endif /* !RT_OS_DARWIN */
 
     /* Prepare update-handlers for known menus: */
@@ -951,23 +939,26 @@ void UIActionPool::preparePool()
 
 void UIActionPool::prepareConnections()
 {
+    /* 'Application' menu connections: */
+#ifdef RT_OS_DARWIN
+    connect(action(UIActionIndex_M_Application_S_About), SIGNAL(triggered()),
+            &msgCenter(), SLOT(sltShowHelpAboutDialog()), Qt::UniqueConnection);
+#endif /* RT_OS_DARWIN */
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+    connect(action(UIActionIndex_M_Application_S_NetworkAccessManager), SIGNAL(triggered()),
+            gNetworkManager, SLOT(show()), Qt::UniqueConnection);
+    connect(action(UIActionIndex_M_Application_S_CheckForUpdates), SIGNAL(triggered()),
+            gUpdateManager, SLOT(sltForceCheck()), Qt::UniqueConnection);
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+    connect(action(UIActionIndex_M_Application_S_ResetWarnings), SIGNAL(triggered()),
+            &msgCenter(), SLOT(sltResetSuppressedMessages()), Qt::UniqueConnection);
+
     /* 'Help' menu connections: */
     connect(action(UIActionIndex_Simple_Contents), SIGNAL(triggered()),
             &msgCenter(), SLOT(sltShowHelpHelpDialog()), Qt::UniqueConnection);
     connect(action(UIActionIndex_Simple_WebSite), SIGNAL(triggered()),
             &msgCenter(), SLOT(sltShowHelpWebDialog()), Qt::UniqueConnection);
-    connect(action(UIActionIndex_Simple_ResetWarnings), SIGNAL(triggered()),
-            &msgCenter(), SLOT(sltResetSuppressedMessages()), Qt::UniqueConnection);
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-    connect(action(UIActionIndex_Simple_NetworkAccessManager), SIGNAL(triggered()),
-            gNetworkManager, SLOT(show()), Qt::UniqueConnection);
-    connect(action(UIActionIndex_Simple_CheckForUpdates), SIGNAL(triggered()),
-            gUpdateManager, SLOT(sltForceCheck()), Qt::UniqueConnection);
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
-#ifdef RT_OS_DARWIN
-    connect(action(UIActionIndex_M_Application_S_About), SIGNAL(triggered()),
-            &msgCenter(), SLOT(sltShowHelpAboutDialog()), Qt::UniqueConnection);
-#else /* !RT_OS_DARWIN */
+#ifndef RT_OS_DARWIN
     connect(action(UIActionIndex_Simple_About), SIGNAL(triggered()),
             &msgCenter(), SLOT(sltShowHelpAboutDialog()), Qt::UniqueConnection);
 #endif /* !RT_OS_DARWIN */
@@ -1031,8 +1022,8 @@ void UIActionPool::updateConfiguration()
     bool fUpdateAllowed = gEDataManager->applicationUpdateEnabled();
     if (!fUpdateAllowed)
     {
-        m_restrictedActionsMenuHelp[UIActionRestrictionLevel_Base] = (UIExtraDataMetaDefs::MenuHelpActionType)
-            (m_restrictedActionsMenuHelp[UIActionRestrictionLevel_Base] | UIExtraDataMetaDefs::MenuHelpActionType_CheckForUpdates);
+        m_restrictedActionsMenuApplication[UIActionRestrictionLevel_Base] = (UIExtraDataMetaDefs::MenuApplicationActionType)
+            (m_restrictedActionsMenuApplication[UIActionRestrictionLevel_Base] | UIExtraDataMetaDefs::MenuApplicationActionType_CheckForUpdates);
     }
 #endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
 
@@ -1047,27 +1038,64 @@ void UIActionPool::updateMenu(int iIndex)
         (this->*(m_menuUpdateHandlers.value(iIndex).ptf))();
 }
 
-#ifdef RT_OS_DARWIN
 void UIActionPool::updateMenuApplication()
 {
     /* Get corresponding menu: */
     UIMenu *pMenu = action(UIActionIndex_M_Application)->menu();
-    AssertReturnVoid(pMenu && pMenu->isConsumable());
+    AssertPtrReturnVoid(pMenu);
+#ifdef RT_OS_DARWIN
+    AssertReturnVoid(pMenu->isConsumable());
+#endif /* RT_OS_DARWIN */
     /* Clear contents: */
+#ifdef RT_OS_DARWIN
     if (!pMenu->isConsumed())
+#endif /* RT_OS_DARWIN */
         pMenu->clear();
 
+    /* Separator: */
+    bool fSeparator = false;
+
+#ifdef RT_OS_DARWIN
     /* 'About' action: */
-    addAction(pMenu, action(UIActionIndex_M_Application_S_About));
+    fSeparator = addAction(pMenu, action(UIActionIndex_M_Application_S_About)) || fSeparator;
+#endif /* RT_OS_DARWIN */
+
     /* 'Preferences' action: */
-    addAction(pMenu, action(UIActionIndex_M_Application_S_Preferences));
+    fSeparator = addAction(pMenu, action(UIActionIndex_M_Application_S_Preferences)) || fSeparator;
+
+#ifndef RT_OS_DARWIN
+    /* Separator: */
+    if (fSeparator)
+    {
+        pMenu->addSeparator();
+        fSeparator = false;
+    }
+#endif /* !RT_OS_DARWIN */
+
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+    /* 'Network Manager' action: */
+    fSeparator = addAction(pMenu, action(UIActionIndex_M_Application_S_NetworkAccessManager)) || fSeparator;
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+    /* 'Reset Warnings' action: */
+    fSeparator = addAction(pMenu, action(UIActionIndex_M_Application_S_ResetWarnings)) || fSeparator;
+
+#ifndef RT_OS_DARWIN
+    /* Separator: */
+    if (fSeparator)
+    {
+        pMenu->addSeparator();
+        fSeparator = false;
+    }
+#endif /* !RT_OS_DARWIN */
+
     /* 'Close' action: */
-    addAction(pMenu, action(UIActionIndex_M_Application_S_Close));
+    fSeparator = addAction(pMenu, action(UIActionIndex_M_Application_S_Close)) || fSeparator;
 
     /* Mark menu as valid: */
     m_invalidations.remove(UIActionIndex_M_Application);
 }
 
+#ifdef RT_OS_DARWIN
 void UIActionPool::updateMenuWindow()
 {
     /* Get corresponding menu: */
@@ -1105,19 +1133,9 @@ void UIActionPool::updateMenuHelp()
     bool fSeparator = false;
 
     /* 'Contents' action: */
-    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_Contents));
+    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_Contents)) || fSeparator;;
     /* 'Web Site' action: */
-    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_WebSite));
-
-    /* Separator? */
-    if (fSeparator)
-    {
-        pMenu->addSeparator();
-        fSeparator = false;
-    }
-
-    /* 'Reset Warnings' action: */
-    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_ResetWarnings));
+    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_WebSite)) || fSeparator;;
 
     /* Separator? */
     if (fSeparator)
@@ -1126,27 +1144,9 @@ void UIActionPool::updateMenuHelp()
         fSeparator = false;
     }
 
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-    /* 'Network Manager' action: */
-    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_NetworkAccessManager));
-    /* 'Check for Updates' action (only for Selector pool): */
-    if (type() == UIActionPoolType_Selector)
-        fSeparator = addAction(pMenu, action(UIActionIndex_Simple_CheckForUpdates));
-
-    /* Separator? */
-    if (fSeparator)
-    {
-        pMenu->addSeparator();
-        fSeparator = false;
-    }
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
-
 #ifndef RT_OS_DARWIN
     /* 'About' action: */
-    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_About));
-    /* 'Preferences' action (only for Runtime pool): */
-    if (type() == UIActionPoolType_Runtime)
-        fSeparator = addAction(pMenu, action(UIActionIndex_Simple_Preferences));
+    fSeparator = addAction(pMenu, action(UIActionIndex_Simple_About)) || fSeparator;;
 #endif /* !RT_OS_DARWIN */
 
     /* Mark menu as valid: */
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.h b/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.h
index d508a95..019aa45 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.h
@@ -51,13 +51,20 @@ enum UIActionType
 /** Action indexes. */
 enum UIActionIndex
 {
-#ifdef RT_OS_DARWIN
     /* 'Application' menu actions: */
     UIActionIndex_M_Application,
+#ifdef RT_OS_DARWIN
     UIActionIndex_M_Application_S_About,
+#endif /* RT_OS_DARWIN */
     UIActionIndex_M_Application_S_Preferences,
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+    UIActionIndex_M_Application_S_NetworkAccessManager,
+    UIActionIndex_M_Application_S_CheckForUpdates,
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+    UIActionIndex_M_Application_S_ResetWarnings,
     UIActionIndex_M_Application_S_Close,
 
+#ifdef RT_OS_DARWIN
     /* 'Window' menu actions: */
     UIActionIndex_M_Window,
     UIActionIndex_M_Window_S_Minimize,
@@ -67,14 +74,8 @@ enum UIActionIndex
     UIActionIndex_Menu_Help,
     UIActionIndex_Simple_Contents,
     UIActionIndex_Simple_WebSite,
-    UIActionIndex_Simple_ResetWarnings,
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-    UIActionIndex_Simple_NetworkAccessManager,
-    UIActionIndex_Simple_CheckForUpdates,
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
 #ifndef RT_OS_DARWIN
     UIActionIndex_Simple_About,
-    UIActionIndex_Simple_Preferences,
 #endif /* !RT_OS_DARWIN */
 
     /* Maximum index: */
@@ -365,15 +366,15 @@ public:
     /** Defines menu-bar @a restriction for passed @a level. */
     void setRestrictionForMenuBar(UIActionRestrictionLevel level, UIExtraDataMetaDefs::MenuType restriction);
 
-#ifdef Q_WS_MAC
     /** Returns whether the action with passed @a type is allowed in the 'Application' menu. */
     bool isAllowedInMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType type) const;
     /** Defines 'Application' menu @a restriction for passed @a level. */
     void setRestrictionForMenuApplication(UIActionRestrictionLevel level, UIExtraDataMetaDefs::MenuApplicationActionType restriction);
 
-    /** Returns whether the action with passed @a type is allowed in the 'Window' menu. */
+#ifdef Q_WS_MAC
+    /** Mac OS X: Returns whether the action with passed @a type is allowed in the 'Window' menu. */
     bool isAllowedInMenuWindow(UIExtraDataMetaDefs::MenuWindowActionType type) const;
-    /** Defines 'Window' menu @a restriction for passed @a level. */
+    /** Mac OS X: Defines 'Window' menu @a restriction for passed @a level. */
     void setRestrictionForMenuWindow(UIActionRestrictionLevel level, UIExtraDataMetaDefs::MenuWindowActionType restriction);
 #endif /* Q_WS_MAC */
 
@@ -424,10 +425,10 @@ protected:
     virtual void updateMenu(int iIndex);
     /** Update menus routine. */
     virtual void updateMenus() = 0;
-#ifdef RT_OS_DARWIN
     /** Update 'Application' menu routine. */
     virtual void updateMenuApplication();
-    /** Update 'Window' menu routine. */
+#ifdef RT_OS_DARWIN
+    /** Mac OS X: Update 'Window' menu routine. */
     virtual void updateMenuWindow();
 #endif /* RT_OS_DARWIN */
     /** Update 'Help' menu routine. */
@@ -461,10 +462,10 @@ protected:
 
     /** Holds restricted menu types. */
     QMap<UIActionRestrictionLevel, UIExtraDataMetaDefs::MenuType> m_restrictedMenus;
-#ifdef Q_WS_MAC
     /** Holds restricted action types of the 'Application' menu. */
     QMap<UIActionRestrictionLevel, UIExtraDataMetaDefs::MenuApplicationActionType> m_restrictedActionsMenuApplication;
-    /** Holds restricted action types of the 'Window' menu. */
+#ifdef Q_WS_MAC
+    /** Mac OS X: Holds restricted action types of the 'Window' menu. */
     QMap<UIActionRestrictionLevel, UIExtraDataMetaDefs::MenuWindowActionType> m_restrictedActionsMenuWindow;
 #endif /* Q_WS_MAC */
     /** Holds restricted action types of the Help menu. */
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
index 87ff3d3..f62d542 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -336,7 +336,7 @@ bool UIMessageCenter::showModalProgressDialog(CProgress &progress,
                                               int cMinDuration /* = 2000 */)
 {
     /* Prepare pixmap: */
-    QPixmap *pPixmap = 0;
+    QPixmap *pPixmap = NULL;
     if (!strImage.isEmpty())
         pPixmap = new QPixmap(strImage);
 
@@ -349,17 +349,22 @@ bool UIMessageCenter::showModalProgressDialog(CProgress &progress,
     pProgressDlg->run(350);
 
     /* Make sure progress-dialog still valid: */
-    if (!pProgressDlg)
-        return false;
+    bool fRc;
+    if (pProgressDlg)
+    {
+        /* Delete progress-dialog: */
+        delete pProgressDlg;
 
-    /* Delete progress-dialog: */
-    delete pProgressDlg;
+        fRc = true;
+    }
+    else
+        fRc = false;
 
     /* Cleanup pixmap: */
     if (pPixmap)
         delete pPixmap;
 
-    return true;
+    return fRc;
 }
 
 #ifdef RT_OS_LINUX
@@ -760,20 +765,20 @@ void UIMessageCenter::cannotResumeMachine(const CConsole &console) const
           formatErrorInfo(console));
 }
 
-void UIMessageCenter::cannotDiscardSavedState(const CConsole &console) const
+void UIMessageCenter::cannotDiscardSavedState(const CMachine &machine) const
 {
     error(0, MessageType_Error,
           tr("Failed to discard the saved state of the virtual machine <b>%1</b>.")
-             .arg(CConsole(console).GetMachine().GetName()),
-          formatErrorInfo(console));
+             .arg(machine.GetName()),
+          formatErrorInfo(machine));
 }
 
-void UIMessageCenter::cannotSaveMachineState(const CConsole &console)
+void UIMessageCenter::cannotSaveMachineState(const CMachine &machine)
 {
     error(0, MessageType_Error,
           tr("Failed to save the state of the virtual machine <b>%1</b>.")
-             .arg(CConsole(console).GetMachine().GetName()),
-          formatErrorInfo(console));
+             .arg(machine.GetName()),
+          formatErrorInfo(machine));
 }
 
 void UIMessageCenter::cannotSaveMachineState(const CProgress &progress, const QString &strMachineName)
@@ -860,12 +865,12 @@ bool UIMessageCenter::warnAboutSnapshotRemovalFreeSpace(const QString &strSnapsh
                           tr("Delete"));
 }
 
-void UIMessageCenter::cannotTakeSnapshot(const CConsole &console, const QString &strMachineName, QWidget *pParent /* = 0*/) const
+void UIMessageCenter::cannotTakeSnapshot(const CMachine &machine, const QString &strMachineName, QWidget *pParent /* = 0*/) const
 {
     error(pParent, MessageType_Error,
           tr("Failed to create a snapshot of the virtual machine <b>%1</b>.")
              .arg(strMachineName),
-          formatErrorInfo(console));
+          formatErrorInfo(machine));
 }
 
 void UIMessageCenter::cannotTakeSnapshot(const CProgress &progress, const QString &strMachineName, QWidget *pParent /* = 0*/) const
@@ -876,12 +881,12 @@ void UIMessageCenter::cannotTakeSnapshot(const CProgress &progress, const QStrin
           formatErrorInfo(progress));
 }
 
-bool UIMessageCenter::cannotRestoreSnapshot(const CConsole &console, const QString &strSnapshotName, const QString &strMachineName) const
+bool UIMessageCenter::cannotRestoreSnapshot(const CMachine &machine, const QString &strSnapshotName, const QString &strMachineName) const
 {
     error(0, MessageType_Error,
           tr("Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
              .arg(strSnapshotName, strMachineName),
-          formatErrorInfo(console));
+          formatErrorInfo(machine));
     return false;
 }
 
@@ -894,12 +899,12 @@ bool UIMessageCenter::cannotRestoreSnapshot(const CProgress &progress, const QSt
     return false;
 }
 
-void UIMessageCenter::cannotRemoveSnapshot(const CConsole &console, const QString &strSnapshotName, const QString &strMachineName) const
+void UIMessageCenter::cannotRemoveSnapshot(const CMachine &machine, const QString &strSnapshotName, const QString &strMachineName) const
 {
     error(0, MessageType_Error,
           tr("Failed to delete the snapshot <b>%1</b> of the virtual machine <b>%2</b>.")
              .arg(strSnapshotName, strMachineName),
-          formatErrorInfo(console));
+          formatErrorInfo(machine));
 }
 
 void UIMessageCenter::cannotRemoveSnapshot(const CProgress &progress, const QString &strSnapshotName, const QString &strMachineName) const
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h b/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h
index 1f1d128..4860429 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -190,8 +190,8 @@ public:
     bool confirmPowerOffMachine(const QString &strNames) const;
     void cannotPauseMachine(const CConsole &console) const;
     void cannotResumeMachine(const CConsole &console) const;
-    void cannotDiscardSavedState(const CConsole &console) const;
-    void cannotSaveMachineState(const CConsole &console);
+    void cannotDiscardSavedState(const CMachine &machine) const;
+    void cannotSaveMachineState(const CMachine &machine);
     void cannotSaveMachineState(const CProgress &progress, const QString &strMachineName);
     void cannotACPIShutdownMachine(const CConsole &console) const;
     void cannotPowerDownMachine(const CConsole &console) const;
@@ -202,11 +202,11 @@ public:
     bool confirmSnapshotRemoval(const QString &strSnapshotName) const;
     bool warnAboutSnapshotRemovalFreeSpace(const QString &strSnapshotName, const QString &strTargetImageName,
                                            const QString &strTargetImageMaxSize, const QString &strTargetFileSystemFree) const;
-    void cannotTakeSnapshot(const CConsole &console, const QString &strMachineName, QWidget *pParent = 0) const;
+    void cannotTakeSnapshot(const CMachine &machine, const QString &strMachineName, QWidget *pParent = 0) const;
     void cannotTakeSnapshot(const CProgress &progress, const QString &strMachineName, QWidget *pParent = 0) const;
-    bool cannotRestoreSnapshot(const CConsole &console, const QString &strSnapshotName, const QString &strMachineName) const;
+    bool cannotRestoreSnapshot(const CMachine &machine, const QString &strSnapshotName, const QString &strMachineName) const;
     bool cannotRestoreSnapshot(const CProgress &progress, const QString &strSnapshotName, const QString &strMachineName) const;
-    void cannotRemoveSnapshot(const CConsole &console, const QString &strSnapshotName, const QString &strMachineName) const;
+    void cannotRemoveSnapshot(const CMachine &machine, const QString &strSnapshotName, const QString &strMachineName) const;
     void cannotRemoveSnapshot(const CProgress &progress, const QString &strSnapshotName, const QString &strMachineName) const;
 
     /* API: Global settings warnings: */
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
index 46092f2..3430c91 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -1322,6 +1322,7 @@ QString VBoxGlobal::detailsReport (const CMachine &aMachine, bool aWithLinks)
                     toCOMPortName (port.GetIRQ(), port.GetIOBase()) + ", ";
                 if (mode == KPortMode_HostPipe ||
                     mode == KPortMode_HostDevice ||
+                    mode == KPortMode_TCP ||
                     mode == KPortMode_RawFile)
                     data += QString ("%1 (<nobr>%2</nobr>)")
                             .arg (gpConverter->toString (mode))
diff --git a/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp b/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp
index 91269f2..513816f 100644
--- a/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2009-2013 Oracle Corporation
+ * Copyright (C) 2009-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -18,10 +18,8 @@
 #ifdef VBOX_WITH_PRECOMPILED_HEADERS
 # include <precomp.h>
 #else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
-
 /* Qt includes: */
 # include <QDir>
-
 /* GUI includes: */
 # include "UIMedium.h"
 # include "VBoxGlobal.h"
@@ -29,42 +27,37 @@
 # include "UIMessageCenter.h"
 # include "UIExtraDataManager.h"
 # include "UIIconPool.h"
-
 /* COM includes: */
 # include "CMachine.h"
 # include "CSnapshot.h"
-
 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
 
-
 QString UIMedium::m_sstrNullID = QUuid().toString().remove('{').remove('}');
 QString UIMedium::m_sstrTable = QString("<table>%1</table>");
 QString UIMedium::m_sstrRow = QString("<tr><td>%1</td></tr>");
 
 UIMedium::UIMedium()
     : m_type(UIMediumType_Invalid)
+    , m_medium(CMedium())
     , m_state(KMediumState_NotCreated)
 {
     refresh();
-//    printf("UIMedium: New NULL medium created.\n");
 }
 
 UIMedium::UIMedium(const CMedium &medium, UIMediumType type)
-    : m_medium(medium)
-    , m_type(type)
+    : m_type(type)
+    , m_medium(medium)
     , m_state(KMediumState_NotCreated)
 {
     refresh();
-//    printf("UIMedium: New medium with ID={%s} created.\n", id().toAscii().constData());
 }
 
 UIMedium::UIMedium(const CMedium &medium, UIMediumType type, KMediumState state)
-    : m_medium(medium)
-    , m_type(type)
+    : m_type(type)
+    , m_medium(medium)
     , m_state(state)
 {
     refresh();
-//    printf("UIMedium: New medium with ID={%s} created (with known state).\n", id().toAscii().constData());
 }
 
 UIMedium::UIMedium(const UIMedium &other)
@@ -74,64 +67,53 @@ UIMedium::UIMedium(const UIMedium &other)
 
 UIMedium& UIMedium::operator=(const UIMedium &other)
 {
-    m_medium = other.medium();
     m_type = other.type();
+
+    m_medium = other.medium();
+
     m_state = other.state();
-    m_strLastAccessError = other.lastAccessError();
     m_result = other.result();
+    m_strLastAccessError = other.lastAccessError();
 
-    m_strKey = other.key();
     m_strId = other.id();
+    m_strRootId = other.rootID();
+    m_strParentId = other.parentID();
+
+    m_strKey = other.key();
+
     m_strName = other.name();
     m_strLocation = other.location();
 
     m_strSize = other.size();
     m_strLogicalSize = other.logicalSize();
 
-    m_strHardDiskFormat = other.hardDiskFormat();
     m_strHardDiskType = other.hardDiskType();
-
+    m_strHardDiskFormat = other.hardDiskFormat();
     m_strStorageDetails = other.storageDetails();
 
     m_strUsage = other.usage();
     m_strToolTip = other.tip();
+    m_machineIds = other.machineIds();
+    m_curStateMachineIds = other.curStateMachineIds();
+
+    m_noDiffs = other.cache();
 
     m_fHidden = other.m_fHidden;
-    m_fAttachedToHiddenMachinesOnly = other.m_fAttachedToHiddenMachinesOnly;
+    m_fUsedByHiddenMachinesOnly = other.m_fUsedByHiddenMachinesOnly;
     m_fReadOnly = other.isReadOnly();
     m_fUsedInSnapshots = other.isUsedInSnapshots();
     m_fHostDrive = other.isHostDrive();
 
-    m_machineIds = other.machineIds();
-    m_curStateMachineIds = other.curStateMachineIds();
-
-    m_strParentID = other.parentID();
-    m_strRootID = other.rootID();
-
-    m_noDiffs = other.cache();
-
     return *this;
 }
 
-/**
- * Queries the medium state. Call this and then read the state field instead
- * of calling GetState() on medium directly as it will properly handle the
- * situation when GetState() itself fails by setting state to Inaccessible
- * and memorizing the error info describing why GetState() failed.
- *
- * As the last step, this method calls #refresh() to refresh all precomposed
- * strings.
- *
- * @note This method blocks for the duration of the state check. Since this
- *       check may take quite a while (e.g. for a medium located on a
- *       network share), the calling thread must not be the UI thread. You
- *       have been warned.
- */
 void UIMedium::blockAndQueryState()
 {
+    /* Ignore for NULL medium: */
     if (m_medium.isNull())
         return;
 
+    /* Acquire actual medium state: */
     m_state = m_medium.RefreshState();
 
     /* Save the result to distinguish between
@@ -145,143 +127,170 @@ void UIMedium::blockAndQueryState()
     else
         m_strLastAccessError = m_medium.GetLastAccessError();
 
+    /* Refresh finally: */
     refresh();
 }
 
-/**
- * Refreshes the precomposed strings containing such media parameters as
- * location, size by querying the respective data from the associated
- * media object.
- *
- * Note that some string such as #size() are meaningless if the media state is
- * KMediumState_NotCreated (i.e. the medium has not yet been checked for
- * accessibility).
- */
 void UIMedium::refresh()
 {
-    /* Flags are 'false' by default: */
-    m_fHidden = false;
-    m_fAttachedToHiddenMachinesOnly = false;
-    m_fReadOnly = false;
-    m_fUsedInSnapshots = false;
-    m_fHostDrive = false;
+    /* Reset ID parameters: */
+    m_strId = nullID();
+    m_strRootId = nullID();
+    m_strParentId = nullID();
 
-    /* Detect basic parameters... */
+    /* Reset cache parameters: */
+    //m_strKey = nullID();
 
-    m_strId = m_medium.isNull() ? nullID() : m_medium.GetId();
+    /* Reset name/location parameters: */
+    m_strName = VBoxGlobal::tr("Empty", "medium");
+    m_strLocation = m_strSize = m_strLogicalSize = QString("--");
 
-    if (m_strKey.isNull() && !m_strId.isNull())
-        m_strKey = m_strId;
+    /* Reset size parameters: */
+    m_strSize = QString();
+    m_strLogicalSize = QString();
 
-    m_fHostDrive = m_medium.isNull() ? false : m_medium.GetHostDrive();
+    /* Reset hard drive related parameters: */
+    m_strHardDiskType = QString();
+    m_strHardDiskFormat = QString();
+    m_strStorageDetails = QString();
 
-    if (m_medium.isNull())
-        m_strName = VBoxGlobal::tr("Empty", "medium");
-    else if (!m_fHostDrive)
-        m_strName = m_medium.GetName();
-    else if (m_medium.GetDescription().isEmpty())
-        m_strName = VBoxGlobal::tr("Host Drive '%1'", "medium").arg(QDir::toNativeSeparators(m_medium.GetLocation()));
-    else
-        m_strName = VBoxGlobal::tr("Host Drive %1 (%2)", "medium").arg(m_medium.GetDescription(), m_medium.GetName());
+    /* Reset data parameters: */
+    m_strUsage = QString();
+    m_strToolTip = QString();
+    m_machineIds.clear();
+    m_curStateMachineIds.clear();
 
-    m_strLocation = m_medium.isNull() || m_fHostDrive ? QString("--") :
-                    QDir::toNativeSeparators(m_medium.GetLocation());
+    /* Reset m_noDiffs: */
+    m_noDiffs.isSet = false;
 
-    QString tmp;
-    if (!m_medium.isNull())
-        tmp = m_medium.GetProperty("Special/GUI/Hints");
-    if (!tmp.isEmpty())
-    {
-        QStringList tmpList(tmp.split(','));
-        if (tmpList.contains("Hide", Qt::CaseInsensitive))
-            m_fHidden = true;
-    }
+    /* Reset flags: */
+    m_fHidden = false;
+    m_fUsedByHiddenMachinesOnly = false;
+    m_fReadOnly = false;
+    m_fUsedInSnapshots = false;
+    m_fHostDrive = false;
 
-    /* Initialize parent/root IDs: */
-    m_strParentID = nullID();
-    m_strRootID = m_strId;
-    if (m_type == UIMediumType_HardDisk)
+    /* For non NULL medium: */
+    if (!m_medium.isNull())
     {
-        m_strHardDiskFormat = m_medium.GetFormat();
-        m_strHardDiskType = vboxGlobal().mediumTypeString(m_medium);
-
-        QVector<KMediumVariant> mediumVariants = m_medium.GetVariant();
-        qlonglong mediumVariant = 0;
-        for (int i = 0; i < mediumVariants.size(); ++i)
-            mediumVariant |= mediumVariants[i];
-
-        m_strStorageDetails = gpConverter->toString((KMediumVariant)mediumVariant);
-        m_fReadOnly = m_medium.GetReadOnly();
+        /* Refresh medium ID: */
+        m_strId = m_medium.GetId();
+        /* Refresh root medium ID: */
+        m_strRootId = m_strId;
+
+        /* Init medium key if necessary: */
+        if (m_strKey.isNull())
+            m_strKey = m_strId;
+
+        /* Check whether this is host-drive medium: */
+        m_fHostDrive = m_medium.GetHostDrive();
+
+        /* Refresh medium name: */
+        if (!m_fHostDrive)
+            m_strName = m_medium.GetName();
+        else if (m_medium.GetDescription().isEmpty())
+            m_strName = VBoxGlobal::tr("Host Drive '%1'", "medium").arg(QDir::toNativeSeparators(m_medium.GetLocation()));
+        else
+            m_strName = VBoxGlobal::tr("Host Drive %1 (%2)", "medium").arg(m_medium.GetDescription(), m_medium.GetName());
+        /* Refresh medium location: */
+        if (!m_fHostDrive)
+            m_strLocation = QDir::toNativeSeparators(m_medium.GetLocation());
 
-        /* Adjust parent/root IDs: */
-        CMedium parentMedium = m_medium.GetParent();
-        if (!parentMedium.isNull())
-            m_strParentID = parentMedium.GetId();
-        while (!parentMedium.isNull())
+        /* Refresh medium size and logical size: */
+        if (!m_fHostDrive)
         {
-            m_strRootID = parentMedium.GetId();
-            parentMedium = parentMedium.GetParent();
+            /* Only for created and accessible mediums: */
+            if (m_state != KMediumState_Inaccessible && m_state != KMediumState_NotCreated)
+            {
+                m_strSize = vboxGlobal().formatSize(m_medium.GetSize());
+                if (m_type == UIMediumType_HardDisk)
+                    m_strLogicalSize = vboxGlobal().formatSize(m_medium.GetLogicalSize());
+                else
+                    m_strLogicalSize = m_strSize;
+            }
         }
-    }
-    else
-    {
-        m_strHardDiskFormat = QString();
-        m_strHardDiskType = QString();
-        m_fReadOnly = false;
-    }
 
-    /* Detect sizes */
-    if (m_state != KMediumState_Inaccessible && m_state != KMediumState_NotCreated && !m_fHostDrive)
-    {
-        m_strSize = vboxGlobal().formatSize(m_medium.GetSize());
+        /* For hard drive medium: */
         if (m_type == UIMediumType_HardDisk)
-            m_strLogicalSize = vboxGlobal().formatSize(m_medium.GetLogicalSize());
-        else
-            m_strLogicalSize = m_strSize;
-    }
-    else
-    {
-        m_strSize = m_strLogicalSize = QString("--");
-    }
+        {
+            /* Refresh hard drive disk type: */
+            m_strHardDiskType = vboxGlobal().mediumTypeString(m_medium);
+            /* Refresh hard drive format: */
+            m_strHardDiskFormat = m_medium.GetFormat();
+
+            /* Refresh hard drive storage details: */
+            qlonglong iMediumVariant = 0;
+            foreach (const KMediumVariant &enmVariant, m_medium.GetVariant())
+                iMediumVariant |= enmVariant;
+            m_strStorageDetails = gpConverter->toString((KMediumVariant)iMediumVariant);
+
+            /* Check whether this is read-only hard drive: */
+            m_fReadOnly = m_medium.GetReadOnly();
+
+            /* Refresh parent hard drive ID: */
+            CMedium parentMedium = m_medium.GetParent();
+            if (!parentMedium.isNull())
+                m_strParentId = parentMedium.GetId();
+
+            /* Only for created and accessible mediums: */
+            if (m_state != KMediumState_Inaccessible && m_state != KMediumState_NotCreated)
+            {
+                /* Refresh root hard drive ID: */
+                while (!parentMedium.isNull())
+                {
+                    m_strRootId = parentMedium.GetId();
+                    parentMedium = parentMedium.GetParent();
+                }
+            }
+        }
 
-    /* Detect usage */
-    m_strUsage = QString();
-    if (!m_medium.isNull())
-    {
+        /* Check whether this is hidden medium: */
+        QString strHints = m_medium.GetProperty("Special/GUI/Hints");
+        if (!strHints.isEmpty())
+        {
+            QStringList hints(strHints.split(','));
+            if (hints.contains("Hide", Qt::CaseInsensitive))
+                m_fHidden = true;
+        }
+
+        /* Refresh usage data: */
         m_curStateMachineIds.clear();
         m_machineIds = m_medium.GetMachineIds().toList();
         if (m_machineIds.size() > 0)
         {
-            /* We assume this flag is 'true' if at least one machine present: */
-            m_fAttachedToHiddenMachinesOnly = true;
-
-            QString strUsage;
-
+            /* Get CVirtualBox object: */
             CVirtualBox vbox = vboxGlobal().virtualBox();
 
+            /* By default we assuming that this medium is attached
+             * to 'hidden' machines only, if at least one machine present: */
+            m_fUsedByHiddenMachinesOnly = true;
+
+            /* Prepare machine usage: */
+            QString strMachineUsage;
+            /* Walk through all the machines this medium attached to: */
             foreach (const QString &strMachineID, m_machineIds)
             {
+                /* Look for the corresponding machine: */
                 CMachine machine = vbox.FindMachine(strMachineID);
 
-                /* UIMedium object can wrap newly created CMedium object which belongs to
-                 * not yet registered machine, like while creating VM clone.
-                 * We can skip such a machines in usage string.
-                 * CVirtualBox::FindMachine() will return null machine for such case. */
+                /* UIMedium object can wrap newly created CMedium object
+                 * which belongs to not yet registered machine, like while creating VM clone.
+                 * We can skip such a machines in usage string. */
                 if (machine.isNull())
                 {
-                    /* We can't decide for that medium yet,
-                     * assume this flag is 'false' for now: */
-                    m_fAttachedToHiddenMachinesOnly = false;
+                    /* Since we can't precisely check 'hidden' status for that machine in such case,
+                     * we have to assume that medium attached not only to 'hidden' machines: */
+                    m_fUsedByHiddenMachinesOnly = false;
                     continue;
                 }
 
-                /* Finally, we are checking if current machine overrides this flag: */
-                if (m_fAttachedToHiddenMachinesOnly && gEDataManager->showMachineInSelectorChooser(strMachineID))
-                    m_fAttachedToHiddenMachinesOnly = false;
-
-                QString strName = machine.GetName();
-                QString strSnapshots;
+                /* Finally we can precisely check if current machine is 'hidden': */
+                if (gEDataManager->showMachineInSelectorChooser(strMachineID))
+                    m_fUsedByHiddenMachinesOnly = false;
 
+                /* Prepare snapshot usage: */
+                QString strSnapshotUsage;
+                /* Walk through all the snapshots this medium attached to: */
                 foreach (const QString &strSnapshotID, m_medium.GetSnapshotIds(strMachineID))
                 {
                     if (strSnapshotID == strMachineID)
@@ -293,48 +302,46 @@ void UIMedium::refresh()
                         continue;
                     }
 
+                    /* Look for the corresponding snapshot: */
                     CSnapshot snapshot = machine.FindSnapshot(strSnapshotID);
-                    if (!snapshot.isNull()) // can be NULL while takeSnaphot is in progress
-                    {
-                        if (!strSnapshots.isNull())
-                            strSnapshots += ", ";
-                        strSnapshots += snapshot.GetName();
-                    }
-                }
-
-                if (!strUsage.isNull())
-                    strUsage += ", ";
 
-                strUsage += strName;
+                    /* Snapshot can be NULL while takeSnaphot is in progress: */
+                    if (snapshot.isNull())
+                        continue;
 
-                if (!strSnapshots.isNull())
-                {
-                    strUsage += QString(" (%2)").arg(strSnapshots);
+                    /* Refresh snapshot usage flag: */
                     m_fUsedInSnapshots = true;
+
+                    /* Append snapshot usage: */
+                    if (!strSnapshotUsage.isNull())
+                        strSnapshotUsage += ", ";
+                    strSnapshotUsage += snapshot.GetName();
                 }
-                else
-                    m_fUsedInSnapshots = false;
+
+                /* Append machine usage: */
+                if (!strMachineUsage.isNull())
+                    strMachineUsage += ", ";
+                strMachineUsage += machine.GetName();
+
+                /* Append snapshot usage: */
+                if (!strSnapshotUsage.isNull())
+                    strMachineUsage += QString(" (%2)").arg(strSnapshotUsage);
             }
 
-            if (!strUsage.isEmpty())
-                m_strUsage = strUsage;
+            /* Append machine usage: */
+            if (!strMachineUsage.isEmpty())
+                m_strUsage += strMachineUsage;
         }
-    }
 
-    /* Compose the tooltip */
-    if (!m_medium.isNull())
-    {
+        /* Refresh tool-tip: */
         m_strToolTip = m_sstrRow.arg(QString("<p style=white-space:pre><b>%1</b></p>").arg(m_fHostDrive ? m_strName : m_strLocation));
-
         if (m_type == UIMediumType_HardDisk)
         {
             m_strToolTip += m_sstrRow.arg(VBoxGlobal::tr("<p style=white-space:pre>Type (Format):  %1 (%2)</p>", "medium")
                                                          .arg(m_strHardDiskType).arg(m_strHardDiskFormat));
         }
-
         m_strToolTip += m_sstrRow.arg(VBoxGlobal::tr("<p>Attached to:  %1</p>", "image")
                                                      .arg(m_strUsage.isNull() ? VBoxGlobal::tr("<i>Not Attached</i>", "image") : m_strUsage));
-
         switch (m_state)
         {
             case KMediumState_NotCreated:
@@ -346,7 +353,7 @@ void UIMedium::refresh()
             {
                 if (m_result.isOk())
                 {
-                    /* Not Accessible */
+                    /* Not Accessible: */
                     m_strToolTip += m_sstrRow.arg("<hr>") + m_sstrRow.arg(VBoxGlobal::highlight(m_strLastAccessError, true /* aToolTip */));
                 }
                 else
@@ -361,47 +368,20 @@ void UIMedium::refresh()
                 break;
         }
     }
-
-    /* Reset m_noDiffs */
-    m_noDiffs.isSet = false;
 }
 
 void UIMedium::updateParentID()
 {
-    m_strParentID = nullID();
+    m_strParentId = nullID();
     if (m_type == UIMediumType_HardDisk)
     {
         CMedium parentMedium = m_medium.GetParent();
         if (!parentMedium.isNull())
-            m_strParentID = parentMedium.GetId();
+            m_strParentId = parentMedium.GetId();
     }
 }
 
-UIMedium UIMedium::parent() const
-{
-    /* Redirect call to VBoxGlobal: */
-    return vboxGlobal().medium(m_strParentID);
-}
-
-UIMedium UIMedium::root() const
-{
-    /* Redirect call to VBoxGlobal: */
-    return vboxGlobal().medium(m_strRootID);
-}
-
-/**
- * Returns generated tooltip for this medium.
- *
- * In "don't show diffs" mode (where the attributes of the base hard disk are
- * shown instead of the attributes of the differencing hard disk), extra
- * information will be added to the tooltip to give the user a hint that the
- * medium is actually a differencing hard disk.
- *
- * @param fNoDiffs  @c true to enable user-friendly "don't show diffs" mode.
- * @param fCheckRO  @c true to perform the #readOnly() check and add a notice
- *                  accordingly.
- */
-QString UIMedium::toolTip (bool fNoDiffs /* = false */, bool fCheckRO /* = false */, bool fNullAllowed /* = false */) const
+QString UIMedium::toolTip(bool fNoDiffs /* = false */, bool fCheckRO /* = false */, bool fNullAllowed /* = false */) const
 {
     QString strTip;
 
@@ -420,27 +400,13 @@ QString UIMedium::toolTip (bool fNoDiffs /* = false */, bool fCheckRO /* = false
 
         if (fCheckRO && m_fReadOnly)
             strTip += m_sstrRow.arg("<hr>") +
-                      m_sstrRow.arg(VBoxGlobal::tr("Attaching this hard disk will be performed indirectly using "
-                                                   "a newly created differencing hard disk.", "medium"));
+                      m_sstrRow.arg(VBoxGlobal::tr("Attaching this hard drive will be performed indirectly using "
+                                                   "a newly created differencing hard drive.", "medium"));
     }
 
     return m_sstrTable.arg(strTip);
 }
 
-/**
- * Returns an icon corresponding to the media state. Distinguishes between
- * the Inaccessible state and the situation when querying the state itself
- * failed.
- *
- * In "don't show diffs" mode (where the attributes of the base hard disk are
- * shown instead of the attributes of the differencing hard disk), the most
- * worst media state on the given hard disk chain will be used to select the
- * media icon.
- *
- * @param fNoDiffs  @c true to enable user-friendly "don't show diffs" mode.
- * @param fCheckRO  @c true to perform the #readOnly() check and change the icon
- *                  accordingly.
- */
 QPixmap UIMedium::icon(bool fNoDiffs /* = false */, bool fCheckRO /* = false */) const
 {
     QPixmap pixmap;
@@ -457,44 +423,20 @@ QPixmap UIMedium::icon(bool fNoDiffs /* = false */, bool fCheckRO /* = false */)
     return pixmap;
 }
 
-/**
- * Returns the details of this medium as a single-line string
- *
- * For hard disks, the details include the location, type and the logical size
- * of the hard disk. Note that if @a fNoDiffs is @c true, these properties are
- * queried on the root hard disk of the given hard disk because the primary
- * purpose of the returned string is to be human readable (so that seeing a
- * complex diff hard disk name is usually not desirable).
- *
- * For other media types, the location and the actual size are returned.
- * Arguments @a fPredictDiff and @a aNoRoot are ignored in this case.
- *
- * @param fNoDiffs      @c true to enable user-friendly "don't show diffs" mode.
- * @param fPredictDiff  @c true to mark the hard disk as differencing if
- *                      attaching it would create a differencing hard disk (not
- *                      used when @a aNoRoot is true).
- * @param fUseHTML      @c true to allow for emphasizing using bold and italics.
- *
- * @note Use #detailsHTML() instead of passing @c true for @a fUseHTML.
- *
- * @note The media object may become uninitialized by a third party while this
- *       method is reading its properties. In this case, the method will return
- *       an empty string.
- */
 QString UIMedium::details(bool fNoDiffs /* = false */,
                           bool fPredictDiff /* = false */,
                           bool fUseHTML /* = false */) const
 {
     // @todo the below check is rough; if m_medium becomes uninitialized, any
     // of getters called afterwards will also fail. The same relates to the
-    // root hard disk object (that will be the hard disk itself in case of
+    // root hard drive object (that will be the hard drive itself in case of
     // non-differencing disks). However, this check was added to fix a
-    // particular use case: when the hard disk is a differencing hard disk and
+    // particular use case: when the hard drive is a differencing hard drive and
     // it happens to be discarded (and uninitialized) after this method is
     // called but before we read all its properties (yes, it's possible!), the
     // root object will be null and calling methods on it will assert in the
     // debug builds. This check seems to be enough as a quick solution (fresh
-    // hard disk attachments will be re-read by a machine state change signal
+    // hard drive attachments will be re-read by a machine state change signal
     // after the discard operation is finished, so the user will eventually see
     // correct data), but in order to solve the problem properly we need to use
     // exceptions everywhere (or check the result after every method call). See
@@ -582,11 +524,18 @@ bool UIMedium::isMediumAttachedToHiddenMachinesOnly(const UIMedium &medium)
     return false;
 }
 
-/**
- * Checks if m_noDiffs is filled in and does it if not.
- *
- * @param fNoDiffs  @if false, this method immediately returns.
- */
+UIMedium UIMedium::root() const
+{
+    /* Redirect call to VBoxGlobal: */
+    return vboxGlobal().medium(m_strRootId);
+}
+
+UIMedium UIMedium::parent() const
+{
+    /* Redirect call to VBoxGlobal: */
+    return vboxGlobal().medium(m_strParentId);
+}
+
 void UIMedium::checkNoDiffs(bool fNoDiffs)
 {
     if (!fNoDiffs || m_noDiffs.isSet)
@@ -602,10 +551,9 @@ void UIMedium::checkNoDiffs(bool fNoDiffs)
             m_noDiffs.state = parentMedium.m_state;
 
             if (m_noDiffs.toolTip.isNull())
-                m_noDiffs.toolTip = m_sstrRow.arg(VBoxGlobal::tr("Some of the files in this hard disk chain "
-                                                                 "are inaccessible. Please use the Virtual Media "
-                                                                 "Manager in <b>Show Differencing Hard Disks</b> "
-                                                                 "mode to inspect these files.", "medium"));
+                m_noDiffs.toolTip = m_sstrRow.arg(VBoxGlobal::tr("Some of the files in this hard drive chain "
+                                                                 "are inaccessible. Please use the Virtual Medium "
+                                                                 "Manager to inspect these files.", "medium"));
 
             if (!parentMedium.m_result.isOk())
             {
@@ -619,8 +567,8 @@ void UIMedium::checkNoDiffs(bool fNoDiffs)
     {
         m_noDiffs.toolTip = root().tip() +
                             m_sstrRow.arg("<hr>") +
-                            m_sstrRow.arg(VBoxGlobal::tr("This base hard disk is indirectly attached using "
-                                                         "the following differencing hard disk:", "medium")) +
+                            m_sstrRow.arg(VBoxGlobal::tr("This base hard drive is indirectly attached using "
+                                                         "the following differencing hard drive:", "medium")) +
                             m_strToolTip + m_noDiffs.toolTip;
     }
 
diff --git a/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h b/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h
index 39407e5..ac7ce25 100644
--- a/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h
+++ b/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (C) 2009-2013 Oracle Corporation
+ * Copyright (C) 2009-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -14,8 +14,8 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
 
-#ifndef __UIMedium_h__
-#define __UIMedium_h__
+#ifndef ___UIMedium_h___
+#define ___UIMedium_h___
 
 /* Qt includes: */
 #include <QMap>
@@ -31,12 +31,15 @@
 /* Other VBox includes: */
 #include "iprt/cpp/utils.h"
 
-/**
- * Cache used to override some attributes in the user-friendly "don't show diffs" mode.
- */
+/** Storage medium cache used to
+  * override some UIMedium attributes in the
+  * user-friendly "don't show diffs" mode. */
 struct NoDiffsCache
 {
+    /** Constructor. */
     NoDiffsCache() : isSet(false), state(KMediumState_NotCreated) {}
+
+    /** Operator= reimplementation. */
     NoDiffsCache& operator=(const NoDiffsCache &other)
     {
         isSet = other.isSet;
@@ -46,233 +49,322 @@ struct NoDiffsCache
         return *this;
     }
 
+    /** Holds whether the cache is set. */
     bool isSet : 1;
 
+    /** Holds overriden medium state. */
     KMediumState state;
+    /** Holds overriden medium acquiring result. */
     COMResult result;
+    /** Holds overriden medium tool-tip. */
     QString toolTip;
 };
 
-/**
- * Media descriptor for the GUI.
- *
- * Maintains the results of the last state (accessibility) check and precomposes
- * string parameters such as location, size which can be used in various GUI
- * controls.
- *
- * Many getter methods take the boolean @a aNoDiffs argument. Unless explicitly
- * stated otherwise, this argument, when set to @c true, will cause the
- * corresponding property of this object's root medium to be returned instead of
- * its own one. This is useful when hard disk media is represented in the
- * user-friendly "don't show diffs" mode. For non-hard disk media, the value of
- * this argument is irrelevant because the root object for such medium is
- * the medium itself.
- *
- * Note that this class "abuses" the KMediumState_NotCreated state value to
- * indicate that the accessibility check of the given medium (see
- * #blockAndQueryState()) has not been done yet and therefore some parameters
- * such as #size() are meaningless because they can be read only from the
- * accessible medium. The real KMediumState_NotCreated state is not necessary
- * because this class is only used with created (existing) media.
- */
+/** Storage medium descriptor wrapping CMedium wrapper for IMedium interface.
+  *
+  * Maintains the results of the last CMedium state (accessibility) check and precomposes
+  * string parameters such as name, location and size which can be used for various GUI tasks.
+  *
+  * Many getter methods take the boolean @a fNoDiffs argument.
+  * Unless explicitly stated otherwise, this argument, when set to @c true,
+  * will cause the corresponding property of this object's root medium to be returned instead
+  * of its own one. This is useful when hard drive medium is reflected in the user-friendly
+  * "don't show diffs" mode. For non-hard drive mediums, the value of this argument is irrelevant
+  * because the root object for such medium is the medium itself.
+  *
+  * Note that this class "abuses" the KMediumState_NotCreated state value to indicate that the
+  * accessibility check of the given medium (see #blockAndQueryState()) has not been done yet
+  * and therefore some parameters such as #size() are meaningless because they can be read only
+  * from the accessible medium. The real KMediumState_NotCreated state is not necessary because
+  * this class is only used with created (existing) mediums. */
 class UIMedium
 {
 public:
 
-    /* Default (NULL) constructor:
-     * Creates NULL uimedium which is not associated with any medium. */
+    /** Default constructor.
+      * Creates NULL UIMedium which is not associated with any CMedium. */
     UIMedium();
 
-    /* Lazy wrapping constructor:
-     * Creates a uimedium associated with the given medium. */
+    /** Lazy wrapping constructor.
+      * Creates the UIMedium associated with the given @a medium of the given @a type. */
     UIMedium(const CMedium &medium, UIMediumType type);
 
-    /* Wrapping constructor with known medium state:
-     * Similar to previous one but sets the uimedium state to passed one.
-     * Suitable when the medium-state is known such as right after medium creation. */
+    /** Wrapping constructor with known medium state.
+      * Similarly to the previous one it creates the UIMedium associated with the
+      * given @a medium of the given @a type but sets the UIMedium @a state to passed one.
+      * Suitable when the medium state is known such as right after the medium creation. */
     UIMedium(const CMedium &medium, UIMediumType type, KMediumState state);
 
-    /* Copy-constructor: */
+    /** Copy constructor.
+      * Creates the UIMedium on the basis of the passed @a other one. */
     UIMedium(const UIMedium &other);
 
-    /* API: Operator=: */
+    /** Operator= reimplementation. */
     UIMedium& operator=(const UIMedium &other);
 
+    /** Queries the actual medium state.
+      * @note This method blocks for the duration of the state check.
+      *       Since this check may take quite a while,
+      *       the calling thread must not be the UI thread. */
     void blockAndQueryState();
+
+    /** Refreshes the precomposed user-readable strings.
+      * @note Note that some string such as #size() are meaningless if the medium state is
+      *       KMediumState_NotCreated (i.e. the medium has not yet been checked for accessibility). */
     void refresh();
 
-    bool isHidden() const { return m_fHidden | m_fAttachedToHiddenMachinesOnly; }
+    /** Returns the type of UIMedium object. */
+    UIMediumType type() const { return m_type; }
 
-    const CMedium &medium() const { return m_medium; }
+    /** Returns the CMedium wrapped by this UIMedium object. */
+    const CMedium& medium() const { return m_medium; }
 
-    UIMediumType type() const { return m_type; }
+    /** Returns @c true if CMedium wrapped by this UIMedium object is a NULL object. */
+    bool isNull() const { return m_medium.isNull(); }
 
-    /**
-     * Media state. In "don't show diffs" mode, this is the worst state (in
-     * terms of inaccessibility) detected on the given hard disk chain.
-     *
-     * @param fNoDiffs  @c true to enable user-friendly "don't show diffs" mode.
-     */
+    /** Returns the medium state.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the worst state
+      *        (in terms of inaccessibility) detected on the given hard drive chain. */
     KMediumState state(bool fNoDiffs = false) const
     {
-        unconst (this)->checkNoDiffs(fNoDiffs);
+        unconst(this)->checkNoDiffs(fNoDiffs);
         return fNoDiffs ? m_noDiffs.state : m_state;
     }
 
-    QString lastAccessError() const { return m_strLastAccessError; }
-
-    /**
-     * Result of the last blockAndQueryState() call. Will indicate an error and
-     * contain a proper error info if the last state check fails. In "don't show
-     * diffs" mode, this is the worst result (in terms of inaccessibility)
-     * detected on the given hard disk chain.
-     *
-     * @param fNoDiffs  @c true to enable user-friendly "don't show diffs" mode.
-     */
-    const COMResult &result(bool fNoDiffs = false) const
+    /** Returns the result of the last blockAndQueryState() call.
+      * Indicates an error and contain a proper error info if the last state check fails.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the worst result
+      *        (in terms of inaccessibility) detected on the given hard drive chain. */
+    const COMResult& result(bool fNoDiffs = false) const
     {
         unconst(this)->checkNoDiffs(fNoDiffs);
         return fNoDiffs ? m_noDiffs.result : m_result;
     }
 
+    /** Returns the error result of the last blockAndQueryState() call. */
+    QString lastAccessError() const { return m_strLastAccessError; }
+
+    /** Returns the medium ID. */
+    QString id() const { return m_strId; }
+
+    /** Returns the medium root ID. */
+    QString rootID() const { return m_strRootId; }
+    /** Returns the medium parent ID. */
+    QString parentID() const { return m_strParentId; }
+
+    /** Updates medium parent. */
+    void updateParentID();
+
+    /** Returns the medium cache key. */
     QString key() const { return m_strKey; }
+    /** Defines the medium cache @a strKey. */
     void setKey(const QString &strKey) { m_strKey = strKey; }
 
-    QString id() const { return m_strId; }
+    /** Returns the medium name.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the name of root in the given hard drive chain. */
     QString name(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strName : m_strName; }
+    /** Returns the medium location.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the location of root in the given hard drive chain. */
     QString location(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strLocation : m_strLocation; }
 
+    /** Returns the medium size.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the size of root in the given hard drive chain. */
     QString size(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strSize : m_strSize; }
+    /** Returns the logical medium size.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the logical size of root in the given hard drive chain. */
     QString logicalSize(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strLogicalSize : m_strLogicalSize; }
 
-    QString hardDiskFormat(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strHardDiskFormat : m_strHardDiskFormat; }
+    /** Returns the hard drive medium disk type.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the disk type of root in the given hard drive chain. */
     QString hardDiskType(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strHardDiskType : m_strHardDiskType; }
+    /** Returns the hard drive medium disk format.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the disk format of root in the given hard drive chain. */
+    QString hardDiskFormat(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strHardDiskFormat : m_strHardDiskFormat; }
 
+    /** Returns the hard drive medium storage details. */
     QString storageDetails() const { return m_strStorageDetails; }
 
+    /** Returns the medium usage data.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @note  In "don't show diffs" mode, this method returns the usage data of root in the given hard drive chain. */
     QString usage(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strUsage : m_strUsage; }
-    QString tip() const { return m_strToolTip; }
 
-    const NoDiffsCache& cache() const { return m_noDiffs; }
+    /** Returns the short version of medium tool-tip. */
+    QString tip() const { return m_strToolTip; }
 
-    /**
-     * Returns @c true if this medium is read-only (either because it is
-     * Immutable or because it has child hard disks). Read-only media can only
-     * be attached indirectly.
-     */
-    bool isReadOnly() const { return m_fReadOnly; }
+    /** Returns the full version of medium tool-tip.
+      * @param fNoDiffs     @c true to enable user-friendly "don't show diffs" mode.
+      * @param fCheckRO     @c true to perform the #readOnly() check and add a notice accordingly.
+      * @param fNullAllowed @c true to allow NULL medium description to be mentioned in the tool-tip.
+      * @note  In "don't show diffs" mode (where the attributes of the base hard drive are shown instead
+      *        of the attributes of the differencing hard drive), extra information will be added to the
+      *        tooltip to give the user a hint that the medium is actually a differencing hard drive. */
+    QString toolTip(bool fNoDiffs = false, bool fCheckRO = false, bool fNullAllowed = false) const;
 
-    /**
-     * Returns @c true if this medium is attached to any VM (in the current
-     * state or in a snapshot) in which case #usage() will contain a string with
-     * comma-separated VM names (with snapshot names, if any, in parenthesis).
-     */
-    bool isUsed() const { return !m_strUsage.isNull(); }
+    /** Shortcut to <tt>#toolTip(fNoDiffs, true, fNullAllowed)</tt>. */
+    QString toolTipCheckRO(bool fNoDiffs = false, bool fNullAllowed = false) const { return toolTip(fNoDiffs, true, fNullAllowed); }
 
-    /**
-     * Returns @c true if this medium is attached to any VM in any snapshot.
-     */
-    bool isUsedInSnapshots() const { return m_fUsedInSnapshots; }
+    /** Returns an icon corresponding to the medium state.
+      * Distinguishes between the Inaccessible state and the situation when querying the state itself failed.
+      * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
+      * @param fCheckRO @c true to perform the #readOnly() check and change the icon accordingly.
+      * @note  In "don't show diffs" mode (where the attributes of the base hard drive are shown instead
+      *        of the attributes of the differencing hard drive), the most worst medium state on the given
+      *        hard drive chain will be used to select the medium icon. */
+    QPixmap icon(bool fNoDiffs = false, bool fCheckRO = false) const;
 
-    /**
-     * Returns @c true if this medium corresponds to real host drive.
-     */
-    bool isHostDrive() const { return m_fHostDrive; }
+    /** Shortcut to <tt>#icon(fNoDiffs, true)</tt>. */
+    QPixmap iconCheckRO(bool fNoDiffs = false) const { return icon(fNoDiffs, true); }
 
-    /**
-     * Returns a vector of IDs of all machines this medium is attached to.
-     */
-    const QList <QString> &machineIds() const { return m_machineIds; }
+    /** Returns the details of this medium as a single-line string.
+      * @param fNoDiffs     @c true to enable user-friendly "don't show diffs" mode.
+      * @param fPredictDiff @c true to mark the hard drive as differencing if attaching
+      *                             it would create a differencing hard drive.
+      * @param fUseHTML     @c true to allow for emphasizing using bold and italics.
+      * @note  For hard drives, the details include the location, type and the logical size of the hard drive.
+      *        Note that if @a fNoDiffs is @c true, these properties are queried on the root hard drive of the
+      *        given hard drive because the primary purpose of the returned string is to be human readable
+      *        (so that seeing a complex diff hard drive name is usually not desirable).
+      * @note  For other medium types, the location and the actual size are returned.
+      *        Arguments @a fPredictDiff and @a fNoDiffs are ignored in this case.
+      * @note  Use #detailsHTML() instead of passing @c true for @a fUseHTML.
+      * @note  The medium object may become uninitialized by a third party while this method is reading its properties.
+      *        In this case, the method will return an empty string. */
+    QString details(bool fNoDiffs = false, bool fPredictDiff = false, bool fUseHTML = false) const;
 
-    /**
-     * Returns @c true if this medium is attached to the given machine in the current state.
-     */
-    bool isAttachedInCurStateTo(const QString &strMachineId) const { return m_curStateMachineIds.indexOf(strMachineId) >= 0; }
+    /** Shortcut to <tt>#details(fNoDiffs, fPredictDiff, true)</tt>. */
+    QString detailsHTML(bool fNoDiffs = false, bool fPredictDiff = false) const { return details(fNoDiffs, fPredictDiff, true); }
 
-    /**
-     * Returns a vector of IDs of all machines this medium is attached
-     * to in their current state (i.e. excluding snapshots).
-     */
-    const QList <QString> &curStateMachineIds() const { return m_curStateMachineIds; }
+    /** Returns the medium cache for "don't show diffs" mode. */
+    const NoDiffsCache& cache() const { return m_noDiffs; }
 
-    /* API: Parent/Root stuff: */
-    void updateParentID();
-    QString parentID() const { return m_strParentID; }
-    QString rootID() const { return m_strRootID; }
-    UIMedium parent() const;
-    UIMedium root() const;
+    /** Returns whether this medium is hidden.
+      * @note The medium is considered 'hidden' if it has corresponding
+      *       medium property or is connected to 'hidden' VMs only. */
+    bool isHidden() const { return m_fHidden | m_fUsedByHiddenMachinesOnly; }
 
-    QString toolTip(bool fNoDiffs = false, bool fCheckRO = false, bool fNullAllowed = false) const;
-    QPixmap icon(bool fNoDiffs = false, bool fCheckRO = false) const;
+    /** Returns whether this medium is read-only
+      * (either because it is Immutable or because it has child hard drives).
+      * @note Read-only medium can only be attached indirectly. */
+    bool isReadOnly() const { return m_fReadOnly; }
 
-    /** Shortcut to <tt>#toolTip(fNoDiffs, true)</tt>. */
-    QString toolTipCheckRO(bool fNoDiffs = false, bool fNullAllowed = false) const { return toolTip(fNoDiffs, true, fNullAllowed); }
+    /** Returns whether this medium is attached to any VM in any snapshot. */
+    bool isUsedInSnapshots() const { return m_fUsedInSnapshots; }
 
-    /** Shortcut to <tt>#icon(fNoDiffs, true)</tt>. */
-    QPixmap iconCheckRO(bool fNoDiffs = false) const { return icon(fNoDiffs, true); }
+    /** Returns whether this medium corresponds to real host drive. */
+    bool isHostDrive() const { return m_fHostDrive; }
 
-    QString details(bool fNoDiffs = false, bool fPredictDiff = false, bool aUseHTML = false) const;
+    /** Returns whether this medium is attached to any VM (in the current state or in a snapshot) in which case
+      * #usage() will contain a string with comma-separated VM names (with snapshot names, if any, in parenthesis). */
+    bool isUsed() const { return !m_strUsage.isNull(); }
 
-    /** Shortcut to <tt>#details(fNoDiffs, fPredictDiff, true)</tt>. */
-    QString detailsHTML(bool fNoDiffs = false, bool fPredictDiff = false) const { return details(fNoDiffs, fPredictDiff, true); }
+    /** Returns whether this medium is attached to the given machine in the current state. */
+    bool isAttachedInCurStateTo(const QString &strMachineId) const { return m_curStateMachineIds.indexOf(strMachineId) >= 0; }
 
-    /** Returns @c true if this media descriptor is a null object. */
-    bool isNull() const { return m_medium.isNull(); }
+    /** Returns a vector of IDs of all machines this medium is attached to. */
+    const QList<QString>& machineIds() const { return m_machineIds; }
+    /** Returns a vector of IDs of all machines this medium is attached to
+      * in their current state (i.e. excluding snapshots). */
+    const QList<QString>& curStateMachineIds() const { return m_curStateMachineIds; }
 
-    /* Static API: Null medium ID: */
+    /** Returns NULL medium ID. */
     static QString nullID();
 
-    /** Determines if passed @a medium attached to hidden machines only. */
+    /** Determines if passed @a medium is attached to hidden machines only. */
     static bool isMediumAttachedToHiddenMachinesOnly(const UIMedium &medium);
 
 private:
 
-    void checkNoDiffs(bool fNoDiffs);
+    /** Returns medium root. */
+    UIMedium root() const;
+    /** Returns medium parent. */
+    UIMedium parent() const;
 
-    CMedium m_medium;
+    /** Checks if m_noDiffs is filled in and does it if not.
+      * @param fNoDiffs @if false, this method immediately returns. */
+    void checkNoDiffs(bool fNoDiffs);
 
+    /** Holds the type of UIMedium object. */
     UIMediumType m_type;
 
+    /** Holds the CMedium wrapped by this UIMedium object. */
+    CMedium m_medium;
+
+    /** Holds the medium state. */
     KMediumState m_state;
-    QString m_strLastAccessError;
+    /** Holds the result of the last blockAndQueryState() call. */
     COMResult m_result;
+    /** Holds the error result of the last blockAndQueryState() call. */
+    QString m_strLastAccessError;
 
-    QString m_strKey;
+    /** Holds the medium ID. */
     QString m_strId;
+    /** Holds the medium root ID. */
+    QString m_strRootId;
+    /** Holds the medium parent ID. */
+    QString m_strParentId;
+
+    /** Holds the medium cache key. */
+    QString m_strKey;
+
+    /** Holds the medium name. */
     QString m_strName;
+    /** Holds the medium location. */
     QString m_strLocation;
 
+    /** Holds the medium size. */
     QString m_strSize;
+    /** Holds the medium logical size. */
     QString m_strLogicalSize;
 
-    QString m_strHardDiskFormat;
+    /** Holds the hard drive medium disk type. */
     QString m_strHardDiskType;
-
+    /** Holds the hard drive medium disk format. */
+    QString m_strHardDiskFormat;
+    /** Holds the hard drive medium storage details. */
     QString m_strStorageDetails;
 
+    /** Holds the medium usage. */
     QString m_strUsage;
+    /** Holds the medium tool-tip. */
     QString m_strToolTip;
-
-    bool m_fHidden                       : 1;
-    bool m_fAttachedToHiddenMachinesOnly : 1;
-    bool m_fReadOnly                     : 1;
-    bool m_fUsedInSnapshots              : 1;
-    bool m_fHostDrive                    : 1;
-
+    /** Holds the vector of IDs of all machines this medium is attached to. */
     QList<QString> m_machineIds;
+    /** Hodls the vector of IDs of all machines this medium is attached to
+      * in their current state (i.e. excluding snapshots). */
     QList<QString> m_curStateMachineIds;
 
-    QString m_strParentID;
-    QString m_strRootID;
-
+    /** Holds the medium cache for "don't show diffs" mode. */
     NoDiffsCache m_noDiffs;
 
+    /** Holds whether this medium is 'hidden' by the corresponding medium property. */
+    bool m_fHidden                   : 1;
+    /** Holds whether this medium is 'hidden' because it's used by 'hidden' VMs only. */
+    bool m_fUsedByHiddenMachinesOnly : 1;
+    /** Holds whether this medium is read-only. */
+    bool m_fReadOnly                 : 1;
+    /** Holds whether this medium is attached to any VM in any snapshot. */
+    bool m_fUsedInSnapshots          : 1;
+    /** Holds whether this medium corresponds to real host drive. */
+    bool m_fHostDrive                : 1;
+
+    /** Holds the NULL medium ID. */
     static QString m_sstrNullID;
+    /** Holds the medium tool-tip table template. */
     static QString m_sstrTable;
+    /** Holds the medium tool-tip table row template. */
     static QString m_sstrRow;
 };
 Q_DECLARE_METATYPE(UIMedium);
 
 typedef QMap<QString, UIMedium> UIMediumMap;
 
-#endif /* __UIMedium_h__ */
+#endif /* !___UIMedium_h___ */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.cpp
index e9911dd..3ff9a59 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.cpp
@@ -341,46 +341,6 @@ protected:
     }
 };
 
-#ifndef RT_OS_DARWIN
-class UIActionSimplePerformClose : public UIActionSimple
-{
-    Q_OBJECT;
-
-public:
-
-    UIActionSimplePerformClose(UIActionPool *pParent)
-        : UIActionSimple(pParent, ":/exit_16px.png")
-    {
-        setMenuRole(QAction::QuitRole);
-    }
-
-protected:
-
-    /** Returns action extra-data ID. */
-    virtual int extraDataID() const { return UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Close;}
-    /** Returns action extra-data key. */
-    virtual QString extraDataKey() const { return gpConverter->toInternalString(UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Close);}
-    /** Returns whether action is allowed. */
-    virtual bool isAllowed() const { return actionPool()->toRuntime()->isAllowedInMenuMachine(UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Close); }
-
-    QString shortcutExtraDataID() const
-    {
-        return QString("Close");
-    }
-
-    QKeySequence defaultShortcut(UIActionPoolType) const
-    {
-        return QKeySequence("Q");
-    }
-
-    void retranslateUi()
-    {
-        setName(QApplication::translate("UIActionPool", "&Close..."));
-        setStatusTip(QApplication::translate("UIActionPool", "Close the virtual machine"));
-    }
-};
-#endif /* !RT_OS_DARWIN */
-
 class UIActionMenuView : public UIActionMenu
 {
     Q_OBJECT;
@@ -1546,7 +1506,7 @@ protected:
 
     void retranslateUi()
     {
-        setName(QApplication::translate("UIActionPool", "Drag'n'Drop"));
+        setName(QApplication::translate("UIActionPool", "Drag and Drop"));
     }
 };
 
@@ -2063,9 +2023,6 @@ void UIActionPoolRuntime::preparePool()
     m_pool[UIActionIndexRT_M_Machine_S_SaveState] = new UIActionSimplePerformSaveState(this);
     m_pool[UIActionIndexRT_M_Machine_S_Shutdown] = new UIActionSimplePerformShutdown(this);
     m_pool[UIActionIndexRT_M_Machine_S_PowerOff] = new UIActionSimplePerformPowerOff(this);
-#ifndef RT_OS_DARWIN
-    m_pool[UIActionIndexRT_M_Machine_S_Close] = new UIActionSimplePerformClose(this);
-#endif /* !RT_OS_DARWIN */
 
     /* 'View' actions: */
     m_pool[UIActionIndexRT_M_View] = new UIActionMenuView(this);
@@ -2181,9 +2138,7 @@ void UIActionPoolRuntime::updateConfiguration()
 
     /* Recache common action restrictions: */
     m_restrictedMenus[UIActionRestrictionLevel_Base] =                  gEDataManager->restrictedRuntimeMenuTypes(strMachineID);
-#ifdef Q_WS_MAC
     m_restrictedActionsMenuApplication[UIActionRestrictionLevel_Base] = gEDataManager->restrictedRuntimeMenuApplicationActionTypes(strMachineID);
-#endif /* Q_WS_MAC */
     m_restrictedActionsMenuMachine[UIActionRestrictionLevel_Base] =     gEDataManager->restrictedRuntimeMenuMachineActionTypes(strMachineID);
     m_restrictedActionsMenuView[UIActionRestrictionLevel_Base] =        gEDataManager->restrictedRuntimeMenuViewActionTypes(strMachineID);
     m_restrictedActionsMenuInput[UIActionRestrictionLevel_Base] =       gEDataManager->restrictedRuntimeMenuInputActionTypes(strMachineID);
@@ -2257,13 +2212,8 @@ void UIActionPoolRuntime::updateConfiguration()
                                       // && (m_restrictedCloseActions & MachineCloseAction_PowerOff_RestoringSnapshot);
     if (fAllCloseActionsRestricted)
     {
-#ifdef Q_WS_MAC
         m_restrictedActionsMenuApplication[UIActionRestrictionLevel_Base] = (UIExtraDataMetaDefs::MenuApplicationActionType)
             (m_restrictedActionsMenuApplication[UIActionRestrictionLevel_Base] | UIExtraDataMetaDefs::MenuApplicationActionType_Close);
-#else /* !Q_WS_MAC */
-        m_restrictedActionsMenuMachine[UIActionRestrictionLevel_Base] = (UIExtraDataMetaDefs::RuntimeMenuMachineActionType)
-            (m_restrictedActionsMenuMachine[UIActionRestrictionLevel_Base] | UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Close);
-#endif /* !Q_WS_MAC */
     }
 
     /* Call to base-class: */
@@ -2286,11 +2236,9 @@ void UIActionPoolRuntime::updateMenus()
     /* Clear menu list: */
     m_mainMenus.clear();
 
-#ifdef RT_OS_DARWIN
     /* 'Application' menu: */
     addMenu(m_mainMenus, action(UIActionIndex_M_Application));
     updateMenuApplication();
-#endif /* RT_OS_DARWIN */
 
     /* 'Machine' menu: */
     addMenu(m_mainMenus, action(UIActionIndexRT_M_Machine));
@@ -2364,18 +2312,6 @@ void UIActionPoolRuntime::updateMenuMachine()
     /* 'PowerOff' action: */
     fSeparator = addAction(pMenu, action(UIActionIndexRT_M_Machine_S_PowerOff)) || fSeparator;
 
-#ifndef Q_WS_MAC
-    /* Separator: */
-    if (fSeparator)
-    {
-        pMenu->addSeparator();
-        fSeparator = false;
-    }
-
-    /* 'Close' action: */
-    fSeparator = addAction(pMenu, action(UIActionIndexRT_M_Machine_S_Close)) || fSeparator;
-#endif /* !Q_WS_MAC */
-
     /* Mark menu as valid: */
     m_invalidations.remove(UIActionIndexRT_M_Machine);
 }
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.h
index d7c83b0..057425b 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.h
@@ -48,9 +48,6 @@ enum UIActionIndexRT
     UIActionIndexRT_M_Machine_S_SaveState,
     UIActionIndexRT_M_Machine_S_Shutdown,
     UIActionIndexRT_M_Machine_S_PowerOff,
-#ifndef RT_OS_DARWIN
-    UIActionIndexRT_M_Machine_S_Close,
-#endif /* !RT_OS_DARWIN */
 
     /* 'View' menu actions: */
     UIActionIndexRT_M_View,
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.cpp
index 36b49ed..b4b6736 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.cpp
@@ -67,6 +67,9 @@ signals:
     /** Notifies listeners about data should be committed. */
     void sigCommitData(QWidget *pThis);
 
+    /** Notifies listeners about Enter/Return key triggering. */
+    void sigEnterKeyTriggered();
+
 public:
 
     /** Constructor.
@@ -83,6 +86,9 @@ private:
     /** Prepare routine. */
     void prepare();
 
+    /** Key press @a pEvent handler. */
+    void keyPressEvent(QKeyEvent *pEvent);
+
     /** Property: Returns the current password of the editor. */
     QString password() const { return QLineEdit::text(); }
     /** Property: Defines the current @a strPassword of the editor. */
@@ -153,6 +159,9 @@ signals:
     /** Notifies listeners about data change. */
     void sigDataChanged();
 
+    /** Notifies listeners about editor's Enter/Return key triggering. */
+    void sigEditorEnterKeyTriggered();
+
 public:
 
     /** Constructor.
@@ -197,8 +206,6 @@ void UIPasswordEditor::sltPasswordChanged(const QString &strPassword)
 
 void UIPasswordEditor::prepare()
 {
-    /* Set alignment: */
-    setAlignment(Qt::AlignCenter);
     /* Set echo mode: */
     setEchoMode(QLineEdit::Password);
     /* Listen for the text changes: */
@@ -206,6 +213,23 @@ void UIPasswordEditor::prepare()
             this, SLOT(sltPasswordChanged(const QString&)));
 }
 
+void UIPasswordEditor::keyPressEvent(QKeyEvent *pEvent)
+{
+    /* Call to base-class: */
+    QLineEdit::keyPressEvent(pEvent);
+
+    /* Broadcast Enter/Return key press: */
+    switch (pEvent->key())
+    {
+        case Qt::Key_Enter:
+        case Qt::Key_Return:
+            emit sigEnterKeyTriggered();
+            break;
+        default:
+            break;
+    }
+}
+
 UIEncryptionDataModel::UIEncryptionDataModel(QObject *pParent, const EncryptedMediumMap &encryptedMediums)
     : QAbstractTableModel(pParent)
     , m_encryptedMediums(encryptedMediums)
@@ -331,17 +355,6 @@ QVariant UIEncryptionDataModel::data(const QModelIndex &index, int iRole /* = Qt
                       encryptedMediums.size())
                       .arg(encryptedMediums.join("<br>"));
         }
-        case Qt::TextAlignmentRole:
-        {
-            /* Depending on column index: */
-            switch (index.column())
-            {
-                case UIEncryptionDataTableSection_Password:
-                    return Qt::AlignCenter;
-                default: return QVariant();
-            }
-            break;
-        }
         default:
             break;
     }
@@ -479,6 +492,10 @@ void UIEncryptionDataTable::prepare()
         /* Assign configured item delegate to table: */
         delete itemDelegate();
         setItemDelegate(pStyledItemDelegate);
+        /* Configure item delegate: */
+        pStyledItemDelegate->setWatchForEditorEnterKeyTriggering(true);
+        connect(pStyledItemDelegate, SIGNAL(sigEditorEnterKeyTriggered()),
+                this, SIGNAL(sigEditorEnterKeyTriggered()));
     }
 
     /* Configure table: */
@@ -521,6 +538,12 @@ EncryptionPasswordMap UIAddDiskEncryptionPasswordDialog::encryptionPasswords() c
     return m_pTableEncryptionData->encryptionPasswords();
 }
 
+void UIAddDiskEncryptionPasswordDialog::sltEditorEnterKeyTriggered()
+{
+    if (m_pButtonBox->button(QDialogButtonBox::Ok)->isEnabled())
+        accept();
+}
+
 void UIAddDiskEncryptionPasswordDialog::prepare()
 {
     /* Configure self: */
@@ -548,6 +571,8 @@ void UIAddDiskEncryptionPasswordDialog::prepare()
                 /* Configure encryption-data table: */
                 connect(m_pTableEncryptionData, SIGNAL(sigDataChanged()),
                         this, SLOT(sltDataChanged()));
+                connect(m_pTableEncryptionData, SIGNAL(sigEditorEnterKeyTriggered()),
+                        this, SLOT(sltEditorEnterKeyTriggered()));
                 m_pTableEncryptionData->setFocus();
                 m_pTableEncryptionData->editFirstIndex();
                 /* Add label into layout: */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.h
index 336acfb..2c3a6c4 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIAddDiskEncryptionPasswordDialog.h
@@ -58,6 +58,9 @@ private slots:
     /** Handles the data change. */
     void sltDataChanged() { revalidate(); }
 
+    /** Handles editor's Enter/Return key triggering. */
+    void sltEditorEnterKeyTriggered();
+
 private:
 
     /** Prepare routine. */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp
index fa11b88..173baa5 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDMIMEData.cpp
@@ -222,7 +222,7 @@ bool UIDnDMimeData::eventFilter(QObject *pObject, QEvent *pEvent)
                 /* ESC pressed? */
                 if (static_cast<QKeyEvent*>(pEvent)->key() == Qt::Key_Escape)
                 {
-                    LogFlowFunc(("ESC pressed, cancelling drag'n drop operation\n"));
+                    LogFlowFunc(("ESC pressed, cancelling drag and drop operation\n"));
                     m_enmState = Canceled;
                 }
 
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
index fe29533..e0b56cc 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
@@ -158,10 +158,15 @@ public:
     /** Defines whether frame-buffer should use unscaled HiDPI output. */
     void setUseUnscaledHiDPIOutput(bool fUseUnscaledHiDPIOutput) { m_fUseUnscaledHiDPIOutput = fUseUnscaledHiDPIOutput; }
 
-    /** Return HiDPI frame-buffer optimization type. */
+    /** Returns frame-buffer scaling optimization type. */
+    ScalingOptimizationType scalingOptimizationType() const { return m_enmScalingOptimizationType; }
+    /** Defines frame-buffer scaling optimization type: */
+    void setScalingOptimizationType(ScalingOptimizationType type) { m_enmScalingOptimizationType = type; }
+
+    /** Returns HiDPI frame-buffer optimization type. */
     HiDPIOptimizationType hiDPIOptimizationType() const { return m_hiDPIOptimizationType; }
-    /** Define HiDPI frame-buffer optimization type: */
-    void setHiDPIOptimizationType(HiDPIOptimizationType optimizationType) { m_hiDPIOptimizationType = optimizationType; }
+    /** Defines HiDPI frame-buffer optimization type: */
+    void setHiDPIOptimizationType(HiDPIOptimizationType type) { m_hiDPIOptimizationType = type; }
 
     DECLARE_NOT_AGGREGATABLE(UIFrameBufferPrivate)
 
@@ -284,6 +289,9 @@ protected:
     /** Paint routine for seamless mode. */
     void paintSeamless(QPaintEvent *pEvent);
 
+    /** Returns the transformation mode corresponding to the passed ScalingOptimizationType. */
+    static Qt::TransformationMode transformationMode(ScalingOptimizationType type);
+
     /** Erases corresponding @a rect with @a painter. */
     static void eraseImageRect(QPainter &painter, const QRect &rect,
                                bool fUseUnscaledHiDPIOutput,
@@ -292,6 +300,7 @@ protected:
     /** Draws corresponding @a rect of passed @a image with @a painter. */
     static void drawImageRect(QPainter &painter, const QImage &image, const QRect &rect,
                               int iContentsShiftX, int iContentsShiftY,
+                              ScalingOptimizationType enmScalingOptimizationType,
                               bool fUseUnscaledHiDPIOutput,
                               HiDPIOptimizationType hiDPIOptimizationType,
                               double dBackingScaleFactor);
@@ -341,6 +350,8 @@ protected:
      * @{ */
     /** Holds the scale-factor used by the scaled-size. */
     double m_dScaleFactor;
+    /** Holds the scaling optimization type used by the scaling mechanism. */
+    ScalingOptimizationType m_enmScalingOptimizationType;
     /** Holds the coordinate-system for the scale-factor above. */
     QTransform m_transform;
     /** Holds the frame-buffer's scaled-size. */
@@ -380,6 +391,8 @@ private:
 #ifdef Q_OS_WIN
      CComPtr <IUnknown> m_pUnkMarshaler;
 #endif /* Q_OS_WIN */
+     /** Identifier returned by AttachFramebuffer. Used in DetachFramebuffer. */
+     QString m_strFramebufferId;
 };
 
 
@@ -517,10 +530,11 @@ UIFrameBufferPrivate::UIFrameBufferPrivate()
     , m_fPendingSourceBitmap(false)
     , m_pMachineView(NULL)
     , m_iWinId(0)
-    , m_fUpdatesAllowed(true)
+    , m_fUpdatesAllowed(false)
     , m_fUnused(false)
     , m_fAutoEnabled(false)
     , m_dScaleFactor(1.0)
+    , m_enmScalingOptimizationType(ScalingOptimizationType_None)
     , m_dBackingScaleFactor(1.0)
     , m_fUseUnscaledHiDPIOutput(false)
     , m_hiDPIOptimizationType(HiDPIOptimizationType_None)
@@ -598,14 +612,17 @@ void UIFrameBufferPrivate::setView(UIMachineView *pMachineView)
 
 void UIFrameBufferPrivate::attach()
 {
-    display().AttachFramebuffer(m_uScreenId, CFramebuffer(this));
+    m_strFramebufferId = display().AttachFramebuffer(m_uScreenId, CFramebuffer(this));
 }
 
 void UIFrameBufferPrivate::detach()
 {
     CFramebuffer frameBuffer = display().QueryFramebuffer(m_uScreenId);
     if (!frameBuffer.isNull())
-        display().DetachFramebuffer(m_uScreenId);
+    {
+        display().DetachFramebuffer(m_uScreenId, m_strFramebufferId);
+        m_strFramebufferId.clear();
+    }
 }
 
 void UIFrameBufferPrivate::setMarkAsUnused(bool fUnused)
@@ -774,10 +791,11 @@ STDMETHODIMP UIFrameBufferPrivate::NotifyUpdate(ULONG uX, ULONG uY, ULONG uWidth
     /* Make sure frame-buffer is used: */
     if (m_fUnused)
     {
+#ifndef DEBUG_andy
         LogRel2(("GUI: UIFrameBufferPrivate::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu, Ignored!\n",
                  (unsigned long)uX, (unsigned long)uY,
                  (unsigned long)uWidth, (unsigned long)uHeight));
-
+#endif
         /* Unlock access to frame-buffer: */
         unlock();
 
@@ -785,11 +803,13 @@ STDMETHODIMP UIFrameBufferPrivate::NotifyUpdate(ULONG uX, ULONG uY, ULONG uWidth
         return E_FAIL;
     }
 
+#ifndef DEBUG_andy
     /* Widget update is NOT thread-safe and *seems* never will be,
      * We have to notify machine-view with the async-signal to perform update operation. */
     LogRel2(("GUI: UIFrameBufferPrivate::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu, Sending to async-handler\n",
              (unsigned long)uX, (unsigned long)uY,
              (unsigned long)uWidth, (unsigned long)uHeight));
+#endif
     emit sigNotifyUpdate(uX, uY, uWidth, uHeight);
 
     /* Unlock access to frame-buffer: */
@@ -822,9 +842,10 @@ STDMETHODIMP UIFrameBufferPrivate::NotifyUpdateImage(ULONG uX, ULONG uY,
         /* Ignore NotifyUpdate: */
         return E_FAIL;
     }
-
-    /* Directly update m_image: */
-    if (m_fUpdatesAllowed)
+    /* Directly update m_image if update fits: */
+    if (   m_fUpdatesAllowed
+        && uX + uWidth <= (ULONG)m_image.width()
+        && uY + uHeight <= (ULONG)m_image.height())
     {
         /* Copy to m_image: */
         uchar *pu8Dst = m_image.bits() + uY * m_image.bytesPerLine() + uX * 4;
@@ -1081,9 +1102,11 @@ void UIFrameBufferPrivate::handleNotifyChange(int iWidth, int iHeight)
 
 void UIFrameBufferPrivate::handlePaintEvent(QPaintEvent *pEvent)
 {
+#ifndef DEBUG_andy
     LogRel2(("GUI: UIFrameBufferPrivate::handlePaintEvent: Origin=%lux%lu, Size=%dx%d\n",
              pEvent->rect().x(), pEvent->rect().y(),
              pEvent->rect().width(), pEvent->rect().height()));
+#endif
 
     /* On mode switch the enqueued paint-event may still come
      * while the machine-view is already null (before the new machine-view set),
@@ -1316,7 +1339,8 @@ void UIFrameBufferPrivate::paintDefault(QPaintEvent *pEvent)
          * detached during scale process, otherwise we can get a frozen frame-buffer. */
         scaledImage = m_image.copy();
         /* And scaling the image to predefined scaled-factor: */
-        scaledImage = scaledImage.scaled(m_scaledSize, Qt::IgnoreAspectRatio, Qt::FastTransformation);
+        scaledImage = scaledImage.scaled(m_scaledSize, Qt::IgnoreAspectRatio,
+                                         transformationMode(scalingOptimizationType()));
     }
     /* Finally we are choosing image to paint from: */
     const QImage &sourceImage = scaledImage.isNull() ? m_image : scaledImage;
@@ -1342,7 +1366,8 @@ void UIFrameBufferPrivate::paintDefault(QPaintEvent *pEvent)
     /* Draw image rectangle: */
     drawImageRect(painter, sourceImage, paintRect,
                   m_pMachineView->contentsX(), m_pMachineView->contentsY(),
-                  useUnscaledHiDPIOutput(), hiDPIOptimizationType(), backingScaleFactor());
+                  scalingOptimizationType(), useUnscaledHiDPIOutput(),
+                  hiDPIOptimizationType(), backingScaleFactor());
 }
 
 void UIFrameBufferPrivate::paintSeamless(QPaintEvent *pEvent)
@@ -1356,7 +1381,8 @@ void UIFrameBufferPrivate::paintSeamless(QPaintEvent *pEvent)
          * detached during scale process, otherwise we can get a frozen frame-buffer. */
         scaledImage = m_image.copy();
         /* And scaling the image to predefined scaled-factor: */
-        scaledImage = scaledImage.scaled(m_scaledSize, Qt::IgnoreAspectRatio, Qt::FastTransformation);
+        scaledImage = scaledImage.scaled(m_scaledSize, Qt::IgnoreAspectRatio,
+                                         transformationMode(scalingOptimizationType()));
     }
     /* Finally we are choosing image to paint from: */
     const QImage &sourceImage = scaledImage.isNull() ? m_image : scaledImage;
@@ -1408,7 +1434,19 @@ void UIFrameBufferPrivate::paintSeamless(QPaintEvent *pEvent)
     /* Paint rectangle: */
     drawImageRect(painter, sourceImage, paintRect,
                   m_pMachineView->contentsX(), m_pMachineView->contentsY(),
-                  useUnscaledHiDPIOutput(), hiDPIOptimizationType(), backingScaleFactor());
+                  scalingOptimizationType(), useUnscaledHiDPIOutput(),
+                  hiDPIOptimizationType(), backingScaleFactor());
+}
+
+/* static */
+Qt::TransformationMode UIFrameBufferPrivate::transformationMode(ScalingOptimizationType type)
+{
+    switch (type)
+    {
+        case ScalingOptimizationType_Performance: return Qt::FastTransformation;
+        default: break;
+    }
+    return Qt::SmoothTransformation;
 }
 
 /* static */
@@ -1460,6 +1498,7 @@ void UIFrameBufferPrivate::eraseImageRect(QPainter &painter, const QRect &rect,
 /* static */
 void UIFrameBufferPrivate::drawImageRect(QPainter &painter, const QImage &image, const QRect &rect,
                                          int iContentsShiftX, int iContentsShiftY,
+                                         ScalingOptimizationType enmScalingOptimizationType,
                                          bool fUseUnscaledHiDPIOutput,
                                          HiDPIOptimizationType hiDPIOptimizationType,
                                          double dBackingScaleFactor)
@@ -1489,7 +1528,7 @@ void UIFrameBufferPrivate::drawImageRect(QPainter &painter, const QImage &image,
         {
             /* Fast scale sub-pixmap (2nd copy involved): */
             subPixmap = subPixmap.scaled(subPixmap.size() * dBackingScaleFactor,
-                                         Qt::IgnoreAspectRatio, Qt::FastTransformation);
+                                         Qt::IgnoreAspectRatio, transformationMode(enmScalingOptimizationType));
         }
 
 #ifdef Q_WS_MAC
@@ -1659,14 +1698,24 @@ void UIFrameBuffer::setUseUnscaledHiDPIOutput(bool fUseUnscaledHiDPIOutput)
     m_pFrameBuffer->setUseUnscaledHiDPIOutput(fUseUnscaledHiDPIOutput);
 }
 
+ScalingOptimizationType UIFrameBuffer::scalingOptimizationType() const
+{
+    return m_pFrameBuffer->scalingOptimizationType();
+}
+
+void UIFrameBuffer::setScalingOptimizationType(ScalingOptimizationType type)
+{
+    m_pFrameBuffer->setScalingOptimizationType(type);
+}
+
 HiDPIOptimizationType UIFrameBuffer::hiDPIOptimizationType() const
 {
     return m_pFrameBuffer->hiDPIOptimizationType();
 }
 
-void UIFrameBuffer::setHiDPIOptimizationType(HiDPIOptimizationType optimizationType)
+void UIFrameBuffer::setHiDPIOptimizationType(HiDPIOptimizationType type)
 {
-    m_pFrameBuffer->setHiDPIOptimizationType(optimizationType);
+    m_pFrameBuffer->setHiDPIOptimizationType(type);
 }
 
 void UIFrameBuffer::handleNotifyChange(int iWidth, int iHeight)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
index 6b10591..aed5263 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
@@ -114,10 +114,15 @@ public:
     /** Defines whether frame-buffer should use unscaled HiDPI output. */
     void setUseUnscaledHiDPIOutput(bool fUseUnscaledHiDPIOutput);
 
-    /** Return HiDPI frame-buffer optimization type. */
+    /** Returns the frame-buffer scaling optimization type. */
+    ScalingOptimizationType scalingOptimizationType() const;
+    /** Defines the frame-buffer scaling optimization type. */
+    void setScalingOptimizationType(ScalingOptimizationType type);
+
+    /** Returns HiDPI frame-buffer optimization type. */
     HiDPIOptimizationType hiDPIOptimizationType() const;
-    /** Define HiDPI frame-buffer optimization type: */
-    void setHiDPIOptimizationType(HiDPIOptimizationType optimizationType);
+    /** Defines HiDPI frame-buffer optimization type: */
+    void setHiDPIOptimizationType(HiDPIOptimizationType type);
 
     /** Handles frame-buffer notify-change-event. */
     void handleNotifyChange(int iWidth, int iHeight);
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
index 59c3e83..3d67eb3 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp
@@ -61,12 +61,10 @@ bool UIMachine::startMachine(const QString &strID)
         /* Which snapshot we are restoring? */
         CSnapshot snapshot = machine.GetCurrentSnapshot();
 
-        /* Open corresponding console: */
-        CConsole console  = session.GetConsole();
         /* Prepare restore-snapshot progress: */
-        CProgress progress = console.RestoreSnapshot(snapshot);
-        if (!console.isOk())
-            return msgCenter().cannotRestoreSnapshot(console, snapshot.GetName(), machine.GetName());
+        CProgress progress = machine.RestoreSnapshot(snapshot);
+        if (!machine.isOk())
+            return msgCenter().cannotRestoreSnapshot(machine, snapshot.GetName(), machine.GetName());
 
         /* Show the snapshot-discarding progress: */
         msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_discard_90px.png");
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
index 83a8651..ce9def1 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
@@ -90,6 +90,7 @@
 
 /* Other VBox includes: */
 # include <iprt/path.h>
+# include <iprt/thread.h>
 # ifdef VBOX_WITH_DEBUGGER_GUI
 #  include <VBox/dbggui.h>
 #  include <iprt/ldr.h>
@@ -558,6 +559,25 @@ void UIMachineLogic::sltMachineStateChanged()
             {
                 /* VM has been powered off, saved, teleported or aborted.
                  * We must close Runtime UI: */
+                if (vboxGlobal().isSeparateProcess())
+                {
+                    /* Hack: The VM process is terminating, so wait a bit to make sure that
+                     * the session is unlocked and the GUI process can save extradata
+                     * in UIMachine::cleanupMachineLogic.
+                     */
+                    /** @todo Probably should wait for the session state change event. */
+                    KSessionState sessionState = uisession()->session().GetState();
+                    int c = 0;
+                    while (   sessionState == KSessionState_Locked
+                           || sessionState == KSessionState_Unlocking)
+                    {
+                         if (++c > 50) break;
+
+                         RTThreadSleep(100);
+                         sessionState = uisession()->session().GetState();
+                    }
+                }
+
                 uisession()->closeRuntimeUI();
                 return;
             }
@@ -992,6 +1012,12 @@ void UIMachineLogic::prepareActionGroups()
 
 void UIMachineLogic::prepareActionConnections()
 {
+    /* 'Application' actions connection: */
+    connect(actionPool()->action(UIActionIndex_M_Application_S_Preferences), SIGNAL(triggered()),
+            this, SLOT(sltShowGlobalPreferences()), Qt::UniqueConnection);
+    connect(actionPool()->action(UIActionIndex_M_Application_S_Close), SIGNAL(triggered()),
+            this, SLOT(sltClose()), Qt::QueuedConnection);
+
     /* 'Machine' actions connections: */
     connect(actionPool()->action(UIActionIndexRT_M_Machine_S_Settings), SIGNAL(triggered()),
             this, SLOT(sltOpenVMSettingsDialog()));
@@ -1009,13 +1035,6 @@ void UIMachineLogic::prepareActionConnections()
             this, SLOT(sltShutdown()));
     connect(actionPool()->action(UIActionIndexRT_M_Machine_S_PowerOff), SIGNAL(triggered()),
             this, SLOT(sltPowerOff()), Qt::QueuedConnection);
-#ifdef RT_OS_DARWIN
-    connect(actionPool()->action(UIActionIndex_M_Application_S_Close), SIGNAL(triggered()),
-            this, SLOT(sltClose()), Qt::QueuedConnection);
-#else /* !RT_OS_DARWIN */
-    connect(actionPool()->action(UIActionIndexRT_M_Machine_S_Close), SIGNAL(triggered()),
-            this, SLOT(sltClose()), Qt::QueuedConnection);
-#endif /* !RT_OS_DARWIN */
 
     /* 'View' actions connections: */
     connect(actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize), SIGNAL(toggled(bool)),
@@ -1077,15 +1096,6 @@ void UIMachineLogic::prepareActionConnections()
     connect(actionPool()->action(UIActionIndex_M_Window_S_Minimize), SIGNAL(triggered()),
             this, SLOT(sltMinimizeActiveMachineWindow()));
 #endif /* Q_WS_MAC */
-
-    /* 'Help' actions connections: */
-#ifdef RT_OS_DARWIN
-    connect(actionPool()->action(UIActionIndex_M_Application_S_Preferences), SIGNAL(triggered()),
-            this, SLOT(sltShowGlobalPreferences()), Qt::UniqueConnection);
-#else /* !RT_OS_DARWIN */
-    connect(actionPool()->action(UIActionIndex_Simple_Preferences), SIGNAL(triggered()),
-            this, SLOT(sltShowGlobalPreferences()), Qt::UniqueConnection);
-#endif /* !RT_OS_DARWIN */
 }
 
 void UIMachineLogic::prepareHandlers()
@@ -1380,16 +1390,6 @@ void UIMachineLogic::sltTakeSnapshot()
     if (!isMachineWindowsCreated())
         return;
 
-    /* Remember the paused state: */
-    bool fWasPaused = uisession()->isPaused();
-    if (!fWasPaused)
-    {
-        /* Suspend the VM and ignore the close event if failed to do so.
-         * pause() will show the error message to the user. */
-        if (!uisession()->pause())
-            return;
-    }
-
     /* Create take-snapshot dialog: */
     QWidget *pDlgParent = windowManager().realParentWindow(activeMachineWindow());
     QPointer<VBoxTakeSnapshotDlg> pDlg = new VBoxTakeSnapshotDlg(pDlgParent, machine());
@@ -1422,8 +1422,8 @@ void UIMachineLogic::sltTakeSnapshot()
     if (fDialogAccepted)
     {
         /* Prepare the take-snapshot progress: */
-        CProgress progress = console().TakeSnapshot(strSnapshotName, strSnapshotDescription);
-        if (console().isOk())
+        CProgress progress = machine().TakeSnapshot(strSnapshotName, strSnapshotDescription, true);
+        if (machine().isOk())
         {
             /* Show the take-snapshot progress: */
             msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_snapshot_create_90px.png");
@@ -1431,16 +1431,7 @@ void UIMachineLogic::sltTakeSnapshot()
                 msgCenter().cannotTakeSnapshot(progress, machineName());
         }
         else
-            msgCenter().cannotTakeSnapshot(console(), machineName());
-    }
-
-    /* Restore the running state if needed: */
-    if (!fWasPaused)
-    {
-        /* Make sure machine-state-change callback is processed: */
-        QApplication::sendPostedEvents(uisession(), UIConsoleEventType_StateChange);
-        /* Unpause VM: */
-        uisession()->unpause();
+            msgCenter().cannotTakeSnapshot(machine(), machineName());
     }
 }
 
@@ -2386,19 +2377,11 @@ void UIMachineLogic::showGlobalPreferences(const QString &strCategory /* = QStri
     if (!isMachineWindowsCreated())
         return;
 
-#ifdef RT_OS_DARWIN
     /* Check that we do NOT handling that already: */
     if (actionPool()->action(UIActionIndex_M_Application_S_Preferences)->data().toBool())
         return;
     /* Remember that we handling that already: */
     actionPool()->action(UIActionIndex_M_Application_S_Preferences)->setData(true);
-#else /* !RT_OS_DARWIN */
-    /* Check that we do NOT handling that already: */
-    if (actionPool()->action(UIActionIndex_Simple_Preferences)->data().toBool())
-        return;
-    /* Remember that we handling that already: */
-    actionPool()->action(UIActionIndex_Simple_Preferences)->setData(true);
-#endif /* !RT_OS_DARWIN */
 
     /* Create and execute global settings window: */
     QPointer<UISettingsDialogGlobal> pDialog = new UISettingsDialogGlobal(activeMachineWindow(),
@@ -2407,13 +2390,8 @@ void UIMachineLogic::showGlobalPreferences(const QString &strCategory /* = QStri
     if (pDialog)
         delete pDialog;
 
-#ifdef RT_OS_DARWIN
     /* Remember that we do NOT handling that already: */
     actionPool()->action(UIActionIndex_M_Application_S_Preferences)->setData(false);
-#else /* !RT_OS_DARWIN */
-    /* Remember that we do NOT handling that already: */
-    actionPool()->action(UIActionIndex_Simple_Preferences)->setData(false);
-#endif /* !RT_OS_DARWIN */
 }
 
 void UIMachineLogic::askUserForTheDiskEncryptionPasswords()
@@ -2439,28 +2417,47 @@ void UIMachineLogic::askUserForTheDiskEncryptionPasswords()
     EncryptionPasswordMap encryptionPasswords;
     if (!encryptedMediums.isEmpty())
     {
-        /* Create corresponding dialog: */
+        /* Create the dialog for acquiring encryption passwords: */
         QWidget *pDlgParent = windowManager().realParentWindow(activeMachineWindow());
         QPointer<UIAddDiskEncryptionPasswordDialog> pDlg =
              new UIAddDiskEncryptionPasswordDialog(pDlgParent,
                                                    machineName(),
                                                    encryptedMediums);
-        /* Execute it and acquire the result: */
+        /* Execute the dialog: */
         if (pDlg->exec() == QDialog::Accepted)
+        {
+            /* Acquire the passwords provided: */
             encryptionPasswords = pDlg->encryptionPasswords();
-        /* Delete dialog if still valid: */
-        if (pDlg)
+
+            /* Delete the dialog: */
             delete pDlg;
-    }
 
-    /* Add the disk encryption passwords if necessary: */
-    if (!encryptionPasswords.isEmpty())
-    {
-        foreach (const QString &strKey, encryptionPasswords.keys())
+            /* Make sure the passwords were really provided: */
+            AssertReturnVoid(!encryptionPasswords.isEmpty());
+
+            /* Apply the disk encryption passwords: */
+            foreach (const QString &strKey, encryptionPasswords.keys())
+            {
+                console().AddDiskEncryptionPassword(strKey, encryptionPasswords.value(strKey), false);
+                if (!console().isOk())
+                    msgCenter().cannotAddDiskEncryptionPassword(console());
+            }
+        }
+        else
         {
-            console().AddDiskEncryptionPassword(strKey, encryptionPasswords.value(strKey), false);
-            if (!console().isOk())
-                msgCenter().cannotAddDiskEncryptionPassword(console());
+            /* Any modal dialog can be destroyed in own event-loop
+             * as a part of VM power-off procedure which closes GUI.
+             * So we have to check if the dialog still valid.. */
+
+            /* If dialog still valid: */
+            if (pDlg)
+            {
+                /* Delete the dialog: */
+                delete pDlg;
+
+                /* Propose the user to close VM: */
+                QMetaObject::invokeMethod(this, "sltClose", Qt::QueuedConnection);
+            }
         }
     }
 }
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
index 715543a..edb5a41 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
@@ -401,6 +401,19 @@ void UIMachineView::sltHandleScaleFactorChange(const QString &strMachineID)
     display().ViewportChanged(screenId(), contentsX(), contentsY(), visibleWidth(), visibleHeight());
 }
 
+void UIMachineView::sltHandleScalingOptimizationChange(const QString &strMachineID)
+{
+    /* Skip unrelated machine IDs: */
+    if (strMachineID != vboxGlobal().managedVMUuid())
+        return;
+
+    /* Take the scale-factor into account: */
+    frameBuffer()->setScalingOptimizationType(gEDataManager->scalingOptimizationType(vboxGlobal().managedVMUuid()));
+
+    /* Update viewport: */
+    viewport()->update();
+}
+
 void UIMachineView::sltHandleUnscaledHiDPIOutputModeChange(const QString &strMachineID)
 {
     /* Skip unrelated machine IDs: */
@@ -674,6 +687,9 @@ void UIMachineView::prepareConnections()
     /* Scale-factor change: */
     connect(gEDataManager, SIGNAL(sigScaleFactorChange(const QString&)),
             this, SLOT(sltHandleScaleFactorChange(const QString&)));
+    /* Scaling-optimization change: */
+    connect(gEDataManager, SIGNAL(sigScalingOptimizationTypeChange(const QString&)),
+            this, SLOT(sltHandleScalingOptimizationChange(const QString&)));
     /* Unscaled HiDPI output mode change: */
     connect(gEDataManager, SIGNAL(sigUnscaledHiDPIOutputModeChange(const QString&)),
             this, SLOT(sltHandleUnscaledHiDPIOutputModeChange(const QString&)));
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
index a71c944..785059a 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
@@ -122,6 +122,9 @@ protected slots:
     /** Handles the scale-factor change. */
     void sltHandleScaleFactorChange(const QString &strMachineID);
 
+    /** Handles the scaling-optimization change. */
+    void sltHandleScalingOptimizationChange(const QString &strMachineID);
+
     /** Handles the unscaled HiDPI output mode change. */
     void sltHandleUnscaledHiDPIOutputModeChange(const QString &strMachineID);
 
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.cpp
index f1c9778..f852053 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.cpp
@@ -134,7 +134,6 @@ void UIMenuBarEditorWidget::sltHandleMenuBarMenuClick()
             gEDataManager->setRestrictedRuntimeMenuTypes(restrictions, machineID());
             break;
         }
-#ifdef Q_WS_MAC
         case UIExtraDataMetaDefs::MenuType_Application:
         {
             /* Get sender type: */
@@ -148,7 +147,6 @@ void UIMenuBarEditorWidget::sltHandleMenuBarMenuClick()
             gEDataManager->setRestrictedRuntimeMenuApplicationActionTypes(restrictions, machineID());
             break;
         }
-#endif /* Q_WS_MAC */
         case UIExtraDataMetaDefs::MenuType_Machine:
         {
             /* Get sender type: */
@@ -336,9 +334,7 @@ void UIMenuBarEditorWidget::prepare()
 void UIMenuBarEditorWidget::prepareMenus()
 {
     /* Create menus: */
-#ifdef Q_WS_MAC
     prepareMenuApplication();
-#endif /* Q_WS_MAC */
     prepareMenuMachine();
     prepareMenuView();
     prepareMenuInput();
@@ -502,18 +498,34 @@ QAction* UIMenuBarEditorWidget::prepareCopiedAction(QMenu *pMenu, const UIAction
     return pCopiedAction;
 }
 
-#ifdef Q_WS_MAC
 void UIMenuBarEditorWidget::prepareMenuApplication()
 {
     /* Copy menu: */
-    QMenu *pMenu = prepareNamedMenu("VirtualBox");
+#ifdef Q_WS_MAC
+    QMenu *pMenu = prepareNamedMenu("Application");
+#else /* !Q_WS_MAC */
+    QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndex_M_Application));
+#endif /* !Q_WS_MAC */
     AssertPtrReturnVoid(pMenu);
     {
+#ifdef Q_WS_MAC
         prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_About));
+# ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_NetworkAccessManager));
+# endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_ResetWarnings));
+        pMenu->addSeparator();
+        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_Preferences));
+#else /* !Q_WS_MAC */
         prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_Preferences));
+        pMenu->addSeparator();
+# ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_NetworkAccessManager));
+# endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
+        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_ResetWarnings));
+#endif /* !Q_WS_MAC */
     }
 }
-#endif /* Q_WS_MAC */
 
 void UIMenuBarEditorWidget::prepareMenuMachine()
 {
@@ -636,15 +648,8 @@ void UIMenuBarEditorWidget::prepareMenuHelp()
         prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_Contents));
         prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_WebSite));
         pMenu->addSeparator();
-        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_ResetWarnings));
-#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
-        pMenu->addSeparator();
-        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_NetworkAccessManager));
-#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
 #ifndef Q_WS_MAC
-        pMenu->addSeparator();
         prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_About));
-        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_Preferences));
 #endif /* !Q_WS_MAC */
     }
 }
@@ -691,9 +696,7 @@ void UIMenuBarEditorWidget::updateMenus()
     }
 
     /* Update known menu-bar menus: */
-#ifdef Q_WS_MAC
     updateMenuApplication();
-#endif /* Q_WS_MAC */
     updateMenuMachine();
     updateMenuView();
     updateMenuInput();
@@ -707,7 +710,6 @@ void UIMenuBarEditorWidget::updateMenus()
     updateMenuHelp();
 }
 
-#ifdef Q_WS_MAC
 void UIMenuBarEditorWidget::updateMenuApplication()
 {
     /* Recache menu-bar configuration: */
@@ -736,7 +738,6 @@ void UIMenuBarEditorWidget::updateMenuApplication()
         m_actions.value(strKey)->setChecked(!(restrictionsMenuApplication & enumValue));
     }
 }
-#endif /* Q_WS_MAC */
 
 void UIMenuBarEditorWidget::updateMenuMachine()
 {
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.h b/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.h
index a9a61d8..4f7842d 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMenuBarEditorWindow.h
@@ -118,10 +118,8 @@ private:
 
     /** Prepare menus routine. */
     void prepareMenus();
-#ifdef Q_WS_MAC
-    /** Mac OS X: Prepare 'Application' menu routine. */
+    /** Prepare 'Application' menu routine. */
     void prepareMenuApplication();
-#endif /* Q_WS_MAC */
     /** Prepare 'Machine' menu routine. */
     void prepareMenuMachine();
     /** Prepare 'View' menu routine. */
@@ -147,10 +145,8 @@ private:
 #endif /* !Q_WS_MAC */
     /** Update menus routine. */
     void updateMenus();
-#ifdef Q_WS_MAC
-    /** Mac OS X: Update 'Application' menu routine. */
+    /** Update 'Application' menu routine. */
     void updateMenuApplication();
-#endif /* Q_WS_MAC */
     /** Update 'Machine' menu routine. */
     void updateMenuMachine();
     /** Update 'View' menu routine. */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
index 3a6999a..f724db9 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -104,13 +104,13 @@ void cgDisplayReconfigurationCallback(CGDirectDisplayID display, CGDisplayChange
 
     /* Handle 'display-add' case: */
     if (flags & kCGDisplayAddFlag)
-        LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display added.\n"));
+        LogRelFlow(("GUI: UISession::cgDisplayReconfigurationCallback: Display added.\n"));
     /* Handle 'display-remove' case: */
     else if (flags & kCGDisplayRemoveFlag)
-        LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display removed.\n"));
+        LogRelFlow(("GUI: UISession::cgDisplayReconfigurationCallback: Display removed.\n"));
     /* Handle 'mode-set' case: */
     else if (flags & kCGDisplaySetModeFlag)
-        LogRelFlow(("UISession::cgDisplayReconfigurationCallback: Display mode changed.\n"));
+        LogRelFlow(("GUI: UISession::cgDisplayReconfigurationCallback: Display mode changed.\n"));
 
     /* Ask handler to process our callback: */
     if (flags & iHandledFlags)
@@ -223,18 +223,18 @@ bool UISession::initialize()
 
 #ifdef VBOX_WITH_VIDEOHWACCEL
     /* Log whether 2D video acceleration is enabled: */
-    LogRel(("2D video acceleration is %s.\n",
+    LogRel(("GUI: 2D video acceleration is %s.\n",
            machine().GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable()
            ? "enabled" : "disabled"));
 #endif /* VBOX_WITH_VIDEOHWACCEL */
 
 /* Log whether HID LEDs sync is enabled: */
 #if defined(Q_WS_MAC) || defined(Q_WS_WIN)
-    LogRel(("HID LEDs sync is %s.\n",
+    LogRel(("GUI: HID LEDs sync is %s.\n",
             uimachine()->machineLogic()->isHidLedsSyncEnabled()
             ? "enabled" : "disabled"));
 #else /* !Q_WS_MAC && !Q_WS_WIN */
-    LogRel(("HID LEDs sync is not supported on this platform.\n"));
+    LogRel(("GUI: HID LEDs sync is not supported on this platform.\n"));
 #endif /* !Q_WS_MAC && !Q_WS_WIN */
 
 #ifdef VBOX_GUI_WITH_PIDFILE
@@ -299,8 +299,8 @@ bool UISession::powerUp()
 bool UISession::saveState()
 {
     /* Prepare the saving progress: */
-    CProgress progress = console().SaveState();
-    if (console().isOk())
+    CProgress progress = machine().SaveState();
+    if (machine().isOk())
     {
         /* Show the saving progress: */
         msgCenter().showModalProgressDialog(progress, machineName(), ":/progress_state_save_90px.png");
@@ -314,7 +314,7 @@ bool UISession::saveState()
     else
     {
         /* Failed in console: */
-        msgCenter().cannotSaveMachineState(console());
+        msgCenter().cannotSaveMachineState(machine());
         return false;
     }
     /* Passed: */
@@ -407,30 +407,30 @@ bool UISession::restoreCurrentSnapshot()
         /* Simulate try-catch block: */
         do
         {
-            /* Acquire console for this session: */
-            CConsole cons = sess.GetConsole();
-            if (cons.isNull())
+            /* Acquire machine for this session: */
+            CMachine machine = sess.GetMachine();
+            if (machine.isNull())
             {
-                /* Unable to acquire console: */
+                /* Unable to acquire machine: */
                 break;
             }
 
             /* Prepare the snapshot-discard progress: */
-            const CSnapshot snap = mach.GetCurrentSnapshot();
-            CProgress prog = cons.RestoreSnapshot(snap);
-            if (!cons.isOk() || prog.isNull())
+            const CSnapshot snap = machine.GetCurrentSnapshot();
+            CProgress prog = machine.RestoreSnapshot(snap);
+            if (!machine.isOk() || prog.isNull())
             {
                 /* Unable to restore snapshot: */
-                msgCenter().cannotRestoreSnapshot(cons, snap.GetName(), machineName());
+                msgCenter().cannotRestoreSnapshot(machine, snap.GetName(), machineName());
                 break;
             }
 
             /* Show the snapshot-discard progress: */
-            msgCenter().showModalProgressDialog(prog, mach.GetName(), ":/progress_snapshot_discard_90px.png");
+            msgCenter().showModalProgressDialog(prog, machine.GetName(), ":/progress_snapshot_discard_90px.png");
             if (prog.GetResultCode() != 0)
             {
                 /* Unable to restore snapshot: */
-                msgCenter().cannotRestoreSnapshot(prog, snap.GetName(), mach.GetName());
+                msgCenter().cannotRestoreSnapshot(prog, snap.GetName(), machine.GetName());
                 break;
             }
 
@@ -673,7 +673,7 @@ void UISession::sltMousePointerShapeChange(bool fVisible, bool fAlpha, QPoint ho
 
 void UISession::sltMouseCapabilityChange(bool fSupportsAbsolute, bool fSupportsRelative, bool fSupportsMultiTouch, bool fNeedsHostCursor)
 {
-    LogRelFlow(("UISession::sltMouseCapabilityChange: "
+    LogRelFlow(("GUI: UISession::sltMouseCapabilityChange: "
                 "Supports absolute: %s, Supports relative: %s, "
                 "Supports multi-touch: %s, Needs host cursor: %s\n",
                 fSupportsAbsolute ? "TRUE" : "FALSE", fSupportsRelative ? "TRUE" : "FALSE",
@@ -800,7 +800,7 @@ void UISession::sltGuestMonitorChange(KGuestMonitorChangedEventType changeType,
  */
 void UISession::sltHandleHostDisplayAboutToChange()
 {
-    LogRelFlow(("UISession::sltHandleHostDisplayAboutToChange()\n"));
+    LogRelFlow(("GUI: UISession::sltHandleHostDisplayAboutToChange()\n"));
 
     if (m_pWatchdogDisplayChange->isActive())
         m_pWatchdogDisplayChange->stop();
@@ -815,7 +815,7 @@ void UISession::sltHandleHostDisplayAboutToChange()
  */
 void UISession::sltCheckIfHostDisplayChanged()
 {
-    LogRelFlow(("UISession::sltCheckIfHostDisplayChanged()\n"));
+    LogRelFlow(("GUI: UISession::sltCheckIfHostDisplayChanged()\n"));
 
     /* Acquire desktop wrapper: */
     QDesktopWidget *pDesktop = QApplication::desktop();
@@ -861,7 +861,7 @@ void UISession::sltCheckIfHostDisplayChanged()
 
 void UISession::sltHandleHostScreenCountChange()
 {
-    LogRelFlow(("UISession: Host-screen count changed.\n"));
+    LogRelFlow(("GUI: UISession: Host-screen count changed.\n"));
 
     /* Recache display data: */
     updateHostScreenData();
@@ -872,7 +872,7 @@ void UISession::sltHandleHostScreenCountChange()
 
 void UISession::sltHandleHostScreenGeometryChange()
 {
-    LogRelFlow(("UISession: Host-screen geometry changed.\n"));
+    LogRelFlow(("GUI: UISession: Host-screen geometry changed.\n"));
 
     /* Recache display data: */
     updateHostScreenData();
@@ -883,7 +883,7 @@ void UISession::sltHandleHostScreenGeometryChange()
 
 void UISession::sltHandleHostScreenAvailableAreaChange()
 {
-    LogRelFlow(("UISession: Host-screen available-area changed.\n"));
+    LogRelFlow(("GUI: UISession: Host-screen available-area changed.\n"));
 
     /* Notify current machine-logic: */
     emit sigHostScreenAvailableAreaChange();
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
index 093d824..af8f571 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp
@@ -250,7 +250,7 @@ void UIMachineWindowFullscreen::prepareMiniToolbar()
     connect(m_pMiniToolBar, SIGNAL(sigExitAction()),
             actionPool()->action(UIActionIndexRT_M_View_T_Fullscreen), SLOT(trigger()));
     connect(m_pMiniToolBar, SIGNAL(sigCloseAction()),
-            actionPool()->action(UIActionIndexRT_M_Machine_S_Close), SLOT(trigger()));
+            actionPool()->action(UIActionIndex_M_Application_S_Close), SLOT(trigger()));
     connect(m_pMiniToolBar, SIGNAL(sigNotifyAboutFocusStolen()),
             this, SLOT(sltRevokeFocus()), Qt::QueuedConnection);
 }
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
index b552d99..378ff29 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
@@ -134,7 +134,7 @@ void UIMachineWindowSeamless::prepareMiniToolbar()
     connect(m_pMiniToolBar, SIGNAL(sigExitAction()),
             actionPool()->action(UIActionIndexRT_M_View_T_Seamless), SLOT(trigger()));
     connect(m_pMiniToolBar, SIGNAL(sigCloseAction()),
-            actionPool()->action(UIActionIndexRT_M_Machine_S_Close), SLOT(trigger()));
+            actionPool()->action(UIActionIndex_M_Application_S_Close), SLOT(trigger()));
     connect(m_pMiniToolBar, SIGNAL(sigNotifyAboutFocusStolen()),
             this, SLOT(sltRevokeFocus()), Qt::QueuedConnection);
 }
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp
index 61a936e..8bf5722 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -319,19 +319,11 @@ void UISelectorWindow::sltOpenExtraDataManagerWindow()
 
 void UISelectorWindow::sltShowPreferencesDialog()
 {
-#ifdef RT_OS_DARWIN
     /* Check that we do NOT handling that already: */
     if (actionPool()->action(UIActionIndex_M_Application_S_Preferences)->data().toBool())
         return;
     /* Remember that we handling that already: */
     actionPool()->action(UIActionIndex_M_Application_S_Preferences)->setData(true);
-#else /* !RT_OS_DARWIN */
-    /* Check that we do NOT handling that already: */
-    if (actionPool()->action(UIActionIndex_Simple_Preferences)->data().toBool())
-        return;
-    /* Remember that we handling that already: */
-    actionPool()->action(UIActionIndex_Simple_Preferences)->setData(true);
-#endif /* !RT_OS_DARWIN */
 
     /* Don't show the inaccessible warning
      * if the user tries to open global settings: */
@@ -341,13 +333,8 @@ void UISelectorWindow::sltShowPreferencesDialog()
     UISettingsDialogGlobal dialog(this);
     dialog.execute();
 
-#ifdef RT_OS_DARWIN
     /* Remember that we do NOT handling that already: */
     actionPool()->action(UIActionIndex_M_Application_S_Preferences)->setData(false);
-#else /* !RT_OS_DARWIN */
-    /* Remember that we do NOT handling that already: */
-    actionPool()->action(UIActionIndex_Simple_Preferences)->setData(false);
-#endif /* !RT_OS_DARWIN */
 }
 
 void UISelectorWindow::sltPerformExit()
@@ -510,11 +497,11 @@ void UISelectorWindow::sltPerformDiscardAction()
         if (session.isNull())
             return;
 
-        /* Get session console: */
-        CConsole console = session.GetConsole();
-        console.DiscardSavedState(true);
-        if (!console.isOk())
-            msgCenter().cannotDiscardSavedState(console);
+        /* Get session machine: */
+        CMachine machine = session.GetMachine();
+        machine.DiscardSavedState(true);
+        if (!machine.isOk())
+            msgCenter().cannotDiscardSavedState(machine);
 
         /* Unlock machine finally: */
         session.UnlockMachine();
@@ -635,22 +622,23 @@ void UISelectorWindow::sltPerformSaveAction()
 
         /* Get session console: */
         CConsole console = session.GetConsole();
+        /* Get session machine: */
+        CMachine machine = session.GetMachine();
         /* Pause VM first: */
         console.Pause();
         if (console.isOk())
         {
             /* Prepare machine state saving: */
-            CProgress progress = console.SaveState();
-            if (console.isOk())
+            CProgress progress = machine.SaveState();
+            if (machine.isOk())
             {
                 /* Show machine state saving progress: */
-                CMachine machine = session.GetMachine();
                 msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_state_save_90px.png");
                 if (!progress.isOk() || progress.GetResultCode() != 0)
                     msgCenter().cannotSaveMachineState(progress, machine.GetName());
             }
             else
-                msgCenter().cannotSaveMachineState(console);
+                msgCenter().cannotSaveMachineState(machine);
         }
         else
             msgCenter().cannotPauseMachine(console);
@@ -1150,22 +1138,28 @@ void UISelectorWindow::prepareMenuFile(QMenu *pMenu)
         return;
 
     /* Populate File-menu: */
-    pMenu->addAction(actionPool()->action(UIActionIndexST_M_File_S_ShowMediumManager));
+#ifdef Q_WS_MAC
+    pMenu->addAction(actionPool()->action(UIActionIndex_M_Application_S_About));
+    pMenu->addAction(actionPool()->action(UIActionIndex_M_Application_S_Preferences));
+#endif /* Q_WS_MAC */
     pMenu->addAction(actionPool()->action(UIActionIndexST_M_File_S_ImportAppliance));
     pMenu->addAction(actionPool()->action(UIActionIndexST_M_File_S_ExportAppliance));
-#ifndef Q_WS_MAC
     pMenu->addSeparator();
-#endif /* Q_WS_MAC */
+    pMenu->addAction(actionPool()->action(UIActionIndexST_M_File_S_ShowMediumManager));
 #ifdef DEBUG
     pMenu->addAction(actionPool()->action(UIActionIndexST_M_File_S_ShowExtraDataManager));
 #endif /* DEBUG */
-#ifdef Q_WS_MAC
-    pMenu->addAction(actionPool()->action(UIActionIndex_M_Application_S_About));
+#ifndef Q_WS_MAC
     pMenu->addAction(actionPool()->action(UIActionIndex_M_Application_S_Preferences));
-#else /* !Q_WS_MAC */
-    pMenu->addAction(actionPool()->action(UIActionIndex_Simple_Preferences));
-    pMenu->addSeparator();
 #endif /* Q_WS_MAC */
+    pMenu->addSeparator();
+#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
+    pMenu->addAction(actionPool()->action(UIActionIndex_M_Application_S_NetworkAccessManager));
+    pMenu->addAction(actionPool()->action(UIActionIndex_M_Application_S_CheckForUpdates));
+# ifndef Q_WS_MAC
+    pMenu->addSeparator();
+# endif /* Q_WS_MAC */
+#endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
     pMenu->addAction(actionPool()->action(UIActionIndexST_M_File_S_Close));
 }
 
@@ -1385,11 +1379,7 @@ void UISelectorWindow::prepareConnections()
 #ifdef DEBUG
     connect(actionPool()->action(UIActionIndexST_M_File_S_ShowExtraDataManager), SIGNAL(triggered()), this, SLOT(sltOpenExtraDataManagerWindow()));
 #endif /* DEBUG */
-#ifdef RT_OS_DARWIN
     connect(actionPool()->action(UIActionIndex_M_Application_S_Preferences), SIGNAL(triggered()), this, SLOT(sltShowPreferencesDialog()));
-#else /* !RT_OS_DARWIN */
-    connect(actionPool()->action(UIActionIndex_Simple_Preferences), SIGNAL(triggered()), this, SLOT(sltShowPreferencesDialog()));
-#endif /* !RT_OS_DARWIN */
     connect(actionPool()->action(UIActionIndexST_M_File_S_Close), SIGNAL(triggered()), this, SLOT(sltPerformExit()));
 
     /* 'Group' menu connections: */
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
index d167312..7a3a2ce 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -640,16 +640,16 @@ void VBoxSnapshotsWgt::sltRestoreSnapshot(bool fSuppressNonCriticalWarnings /* =
         return;
 
     /* Restore chosen snapshot: */
-    CConsole console = session.GetConsole();
-    CProgress progress = console.RestoreSnapshot(snapshot);
-    if (console.isOk())
+    CMachine machine = session.GetMachine();
+    CProgress progress = machine.RestoreSnapshot(snapshot);
+    if (machine.isOk())
     {
         msgCenter().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_restore_90px.png");
         if (progress.GetResultCode() != 0)
             msgCenter().cannotRestoreSnapshot(progress, snapshot.GetName(), mMachine.GetName());
     }
     else
-        msgCenter().cannotRestoreSnapshot(console, snapshot.GetName(), mMachine.GetName());
+        msgCenter().cannotRestoreSnapshot(machine, snapshot.GetName(), mMachine.GetName());
 
     /* Unlock machine finally: */
     session.UnlockMachine();
@@ -687,9 +687,10 @@ void VBoxSnapshotsWgt::sltDeleteSnapshot()
     if (session.isNull())
         return;
 
-    CConsole console = session.GetConsole();
-    CProgress progress = console.DeleteSnapshot (snapId);
-    if (console.isOk())
+    /* Remove chosen snapshot: */
+    CMachine machine = session.GetMachine();
+    CProgress progress = machine.DeleteSnapshot(snapId);
+    if (machine.isOk())
     {
         /* Show the progress dialog */
         msgCenter().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_discard_90px.png");
@@ -698,7 +699,7 @@ void VBoxSnapshotsWgt::sltDeleteSnapshot()
             msgCenter().cannotRemoveSnapshot(progress,  snapshot.GetName(), mMachine.GetName());
     }
     else
-        msgCenter().cannotRemoveSnapshot(console,  snapshot.GetName(), mMachine.GetName());
+        msgCenter().cannotRemoveSnapshot(machine,  snapshot.GetName(), mMachine.GetName());
 
     session.UnlockMachine();
 }
@@ -828,103 +829,71 @@ bool VBoxSnapshotsWgt::takeSnapshot()
 
     if (fIsValid)
     {
-        /* Get corresponding console object also: */
-        CConsole console = session.GetConsole();
-        /* Remember runtime state: */
-        bool fAtRuntime = mMachine.GetState() == KMachineState_Running;
-        /* Remember paused state: */
-        bool fWasPaused = mMachine.GetState() == KMachineState_Paused ||
-                          mMachine.GetState() == KMachineState_TeleportingPausedVM;
-
-        /* Pause VM if necessary: */
-        if (fIsValid && fAtRuntime && !fWasPaused)
+        /* Get corresponding machine object also: */
+        CMachine machine = session.GetMachine();
+
+        /* Create take-snapshot dialog: */
+        QWidget *pDlgParent = windowManager().realParentWindow(this);
+        QPointer<VBoxTakeSnapshotDlg> pDlg = new VBoxTakeSnapshotDlg(pDlgParent, mMachine);
+        windowManager().registerNewParent(pDlg, pDlgParent);
+
+        /* Assign corresponding icon: */
+        pDlg->mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(mMachine.GetOSTypeId()));
+
+        /* Search for the max available snapshot index: */
+        int iMaxSnapShotIndex = 0;
+        QString snapShotName = tr("Snapshot %1");
+        QRegExp regExp(QString("^") + snapShotName.arg("([0-9]+)") + QString("$"));
+        QTreeWidgetItemIterator iterator(mTreeWidget);
+        while (*iterator)
         {
-            /* Pausing VM: */
-            console.Pause();
-            if (!console.isOk())
-            {
-                msgCenter().cannotPauseMachine(console);
-                fIsValid = false;
-            }
+            QString snapShot = static_cast<SnapshotWgtItem*>(*iterator)->text(0);
+            int pos = regExp.indexIn(snapShot);
+            if (pos != -1)
+                iMaxSnapShotIndex = regExp.cap(1).toInt() > iMaxSnapShotIndex ? regExp.cap(1).toInt() : iMaxSnapShotIndex;
+            ++iterator;
         }
+        pDlg->mLeName->setText(snapShotName.arg(iMaxSnapShotIndex + 1));
 
-        if (fIsValid)
+        /* Exec the dialog: */
+        bool fDialogAccepted = pDlg->exec() == QDialog::Accepted;
+
+        /* Is the dialog still valid? */
+        if (pDlg)
         {
-            /* Create take-snapshot dialog: */
-            QWidget *pDlgParent = windowManager().realParentWindow(this);
-            QPointer<VBoxTakeSnapshotDlg> pDlg = new VBoxTakeSnapshotDlg(pDlgParent, mMachine);
-            windowManager().registerNewParent(pDlg, pDlgParent);
-
-            /* Assign corresponding icon: */
-            pDlg->mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(mMachine.GetOSTypeId()));
-
-            /* Search for the max available snapshot index: */
-            int iMaxSnapShotIndex = 0;
-            QString snapShotName = tr("Snapshot %1");
-            QRegExp regExp(QString("^") + snapShotName.arg("([0-9]+)") + QString("$"));
-            QTreeWidgetItemIterator iterator(mTreeWidget);
-            while (*iterator)
-            {
-                QString snapShot = static_cast<SnapshotWgtItem*>(*iterator)->text(0);
-                int pos = regExp.indexIn(snapShot);
-                if (pos != -1)
-                    iMaxSnapShotIndex = regExp.cap(1).toInt() > iMaxSnapShotIndex ? regExp.cap(1).toInt() : iMaxSnapShotIndex;
-                ++iterator;
-            }
-            pDlg->mLeName->setText(snapShotName.arg(iMaxSnapShotIndex + 1));
+            /* Acquire variables: */
+            QString strSnapshotName = pDlg->mLeName->text().trimmed();
+            QString strSnapshotDescription = pDlg->mTeDescription->toPlainText();
 
-            /* Exec the dialog: */
-            bool fDialogAccepted = pDlg->exec() == QDialog::Accepted;
+            /* Destroy dialog early: */
+            delete pDlg;
 
-            /* Is the dialog still valid? */
-            if (pDlg)
+            /* Was the dialog accepted? */
+            if (fDialogAccepted)
             {
-                /* Acquire variables: */
-                QString strSnapshotName = pDlg->mLeName->text().trimmed();
-                QString strSnapshotDescription = pDlg->mTeDescription->toPlainText();
-
-                /* Destroy dialog early: */
-                delete pDlg;
-
-                /* Was the dialog accepted? */
-                if (fDialogAccepted)
+                /* Prepare the take-snapshot progress: */
+                CProgress progress = machine.TakeSnapshot(strSnapshotName, strSnapshotDescription, true);
+                if (machine.isOk())
                 {
-                    /* Prepare the take-snapshot progress: */
-                    CProgress progress = console.TakeSnapshot(strSnapshotName, strSnapshotDescription);
-                    if (console.isOk())
-                    {
-                        /* Show the take-snapshot progress: */
-                        msgCenter().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_create_90px.png");
-                        if (!progress.isOk() || progress.GetResultCode() != 0)
-                        {
-                            msgCenter().cannotTakeSnapshot(progress, mMachine.GetName());
-                            fIsValid = false;
-                        }
-                    }
-                    else
+                    /* Show the take-snapshot progress: */
+                    msgCenter().showModalProgressDialog(progress, mMachine.GetName(), ":/progress_snapshot_create_90px.png");
+                    if (!progress.isOk() || progress.GetResultCode() != 0)
                     {
-                        msgCenter().cannotTakeSnapshot(console, mMachine.GetName());
+                        msgCenter().cannotTakeSnapshot(progress, mMachine.GetName());
                         fIsValid = false;
                     }
                 }
                 else
+                {
+                    msgCenter().cannotTakeSnapshot(machine, mMachine.GetName());
                     fIsValid = false;
+                }
             }
             else
                 fIsValid = false;
         }
-
-        /* Resume VM if necessary: */
-        if (fIsValid && fAtRuntime && !fWasPaused)
-        {
-            /* Resuming VM: */
-            console.Resume();
-            if (!console.isOk())
-            {
-                msgCenter().cannotResumeMachine(console);
-                fIsValid = false;
-            }
-        }
+        else
+            fIsValid = false;
 
         /* Unlock machine finally: */
         session.UnlockMachine();
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp b/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp
index a6942b3..b0ad45e 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp
@@ -240,6 +240,7 @@ void UIGChooserItemMachine::updateStatePixmap()
 {
     /* Get new state-pixmap and state-pixmap size: */
     const QIcon stateIcon = machineStateIcon();
+    AssertReturnVoid(!stateIcon.isNull());
     const QSize statePixmapSize = stateIcon.availableSizes().first();
     const QPixmap statePixmap = stateIcon.pixmap(statePixmapSize);
     /* Update linked values: */
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElements.cpp b/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElements.cpp
index c79f06f..3d380b3 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElements.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElements.cpp
@@ -807,7 +807,8 @@ void UIGDetailsUpdateThreadSerial::run()
                 {
                     KPortMode mode = port.GetHostMode();
                     QString data = vboxGlobal().toCOMPortName(port.GetIRQ(), port.GetIOBase()) + ", ";
-                    if (mode == KPortMode_HostPipe || mode == KPortMode_HostDevice || mode == KPortMode_RawFile)
+                    if (mode == KPortMode_HostPipe || mode == KPortMode_HostDevice ||
+                        mode == KPortMode_RawFile || mode == KPortMode_TCP)
                         data += QString("%1 (%2)").arg(gpConverter->toString(mode)).arg(QDir::toNativeSeparators(port.GetPath()));
                     else
                         data += gpConverter->toString(mode);
@@ -936,9 +937,17 @@ void UIGDetailsUpdateThreadUSB::run()
             const CUSBDeviceFilters &filters = machine().GetUSBDeviceFilters();
             if (!filters.isNull() && machine().GetUSBProxyAvailable())
             {
-                const CUSBDeviceFilters &flts = machine().GetUSBDeviceFilters();
-                if (!flts.isNull() && !machine().GetUSBControllers().isEmpty())
+                const CUSBDeviceFilters flts = machine().GetUSBDeviceFilters();
+                const CUSBControllerVector controllers = machine().GetUSBControllers();
+                if (!flts.isNull() && !controllers.isEmpty())
                 {
+                    /* USB Controllers info: */
+                    QStringList controllerList;
+                    foreach (const CUSBController &controller, controllers)
+                        controllerList << gpConverter->toString(controller.GetType());
+                    m_text << UITextTableLine(QApplication::translate("UIGDetails", "USB Controller", "details (usb)"),
+                                              controllerList.join(", "));
+                    /* USB Device Filters info: */
                     const CUSBDeviceFilterVector &coll = flts.GetDeviceFilters();
                     uint uActive = 0;
                     for (int i = 0; i < coll.size(); ++i)
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp
index fa3cd99..a700102 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsGeneral.cpp
@@ -563,7 +563,6 @@ void UIMachineSettingsGeneral::prepareTabEncryption()
     AssertPtrReturnVoid(m_pEditorEncryptionPassword);
     {
         /* Configure Encryption Password editor: */
-        m_pEditorEncryptionPassword->setAlignment(Qt::AlignCenter);
         m_pEditorEncryptionPassword->setEchoMode(QLineEdit::Password);
         connect(m_pEditorEncryptionPassword, SIGNAL(textEdited(const QString&)),
                 this, SLOT(sltMarkEncryptionPasswordChanged()));
@@ -574,7 +573,6 @@ void UIMachineSettingsGeneral::prepareTabEncryption()
     AssertPtrReturnVoid(m_pEditorEncryptionPasswordConfirm);
     {
         /* Configure Encryption Password Confirmation editor: */
-        m_pEditorEncryptionPasswordConfirm->setAlignment(Qt::AlignCenter);
         m_pEditorEncryptionPasswordConfirm->setEchoMode(QLineEdit::Password);
         connect(m_pEditorEncryptionPasswordConfirm, SIGNAL(textEdited(const QString&)),
                 this, SLOT(sltMarkEncryptionPasswordChanged()));
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp
index dd3b9dc..9210046 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp
@@ -662,7 +662,7 @@ bool UIMachineSettingsSF::isSharedFolderTypeSupported(UISharedFolderType sharedF
             fIsSharedFolderTypeSupported = isMachineInValidMode();
             break;
         case ConsoleType:
-            fIsSharedFolderTypeSupported = isMachineSaved() || isMachineOnline();
+            fIsSharedFolderTypeSupported = isMachineOnline();
             break;
         default:
             break;
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp
index e8c5462..6f4c901 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -62,6 +62,7 @@ UIMachineSettingsSerial::UIMachineSettingsSerial(UIMachineSettingsSerialPage *pP
     mCbMode->addItem (""); /* KPortMode_HostPipe */
     mCbMode->addItem (""); /* KPortMode_HostDevice */
     mCbMode->addItem (""); /* KPortMode_RawFile */
+    mCbMode->addItem (""); /* KPortMode_TCP */
 
     /* Setup connections */
     connect (mGbSerial, SIGNAL (toggled (bool)),
@@ -93,7 +94,8 @@ void UIMachineSettingsSerial::polishTab()
     mLeIOPort->setEnabled(!fStd && m_pParent->isMachineOffline());
     mLbMode->setEnabled(m_pParent->isMachineOffline());
     mCbMode->setEnabled(m_pParent->isMachineOffline());
-    mCbPipe->setEnabled(mode == KPortMode_HostPipe && m_pParent->isMachineOffline());
+    mCbPipe->setEnabled((mode == KPortMode_HostPipe || mode == KPortMode_TCP)
+      && m_pParent->isMachineOffline());
     mLbPath->setEnabled(m_pParent->isMachineOffline());
     mLePath->setEnabled(mode != KPortMode_Disconnected && m_pParent->isMachineOffline());
 }
@@ -166,6 +168,7 @@ void UIMachineSettingsSerial::retranslateUi()
 
     mCbNumber->setItemText (mCbNumber->count() - 1, vboxGlobal().toCOMPortName (0, 0));
 
+    mCbMode->setItemText (4, gpConverter->toString (KPortMode_TCP));
     mCbMode->setItemText (3, gpConverter->toString (KPortMode_RawFile));
     mCbMode->setItemText (2, gpConverter->toString (KPortMode_HostDevice));
     mCbMode->setItemText (1, gpConverter->toString (KPortMode_HostPipe));
@@ -204,7 +207,7 @@ void UIMachineSettingsSerial::mCbNumberActivated (const QString &aText)
 void UIMachineSettingsSerial::mCbModeActivated (const QString &aText)
 {
     KPortMode mode = gpConverter->fromString<KPortMode> (aText);
-    mCbPipe->setEnabled (mode == KPortMode_HostPipe);
+    mCbPipe->setEnabled (mode == KPortMode_HostPipe || mode == KPortMode_TCP);
     mLePath->setEnabled (mode != KPortMode_Disconnected);
 
     /* Revalidate: */
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.ui b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.ui
index c87b349..6db1c3c 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.ui
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.ui
@@ -2,7 +2,7 @@
  <comment>
  VBox frontends: Qt4 GUI ("VirtualBox"):
 
- Copyright (C) 2008-2012 Oracle Corporation
+ Copyright (C) 2008-2015 Oracle Corporation
 
  This file is part of VirtualBox Open Source Edition (OSE), as
  available from http://www.virtualbox.org. This file is free software;
@@ -176,17 +176,17 @@
       <item row="2" column="1" colspan="2" >
        <widget class="QCheckBox" name="mCbPipe" >
         <property name="whatsThis" >
-         <string>If checked, the pipe specified in the <b>Port Path</b> field will be created by the virtual machine when it starts. Otherwise, the virtual machine will assume that the pipe exists and try to use it.</string>
+         <string>If checked, the pipe or socket specified in the <b>Port Path</b> field will be created by the virtual machine when it starts. Otherwise, the virtual machine will assume that the pipe or socket exists and try to use it.</string>
         </property>
         <property name="text" >
-         <string>&Create Pipe</string>
+         <string>&Connect to existing pipe/socket</string>
         </property>
        </widget>
       </item>
       <item row="3" column="0" >
        <widget class="QLabel" name="mLbPath" >
         <property name="text" >
-         <string>Port/File &Path:</string>
+         <string>&Path/Address:</string>
         </property>
         <property name="alignment" >
          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -199,7 +199,12 @@
       <item row="3" column="1" colspan="6" >
        <widget class="QLineEdit" name="mLePath" >
         <property name="whatsThis" >
-         <string>Holds the path to the serial port's pipe on the host when the port is working in <b>Host Pipe</b> mode, or the host serial device name when the port is working in <b>Host Device</b> mode.</string>
+         <string>In <b>Host Pipe</b> mode: Holds the path to the serial port's pipe on the host, examples:
+"\\.\pipe\myvbox" or "/tmp/myvbox", for Windows and UNIX-like systems respectively. 
+In <b>Host Device</b> mode: Holds the host serial device name; examples: "COM1" or "/dev/ttyS0".
+In <b>Raw file</b> mode: file-path on the host system, where serial output will be dumped.
+In <b>TCP</b> mode: Holds TCP "port" when in server mode, or "hostname:port" or when in client mode.
+</string>
         </property>
        </widget>
       </item>
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/UIFilmContainer.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/UIFilmContainer.cpp
old mode 100644
new mode 100755
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVM.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVM.cpp
index 424d5ca..b5195db 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVM.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVM.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2011-2013 Oracle Corporation
+ * Copyright (C) 2011-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -78,14 +78,14 @@ bool UIWizardCloneVM::cloneVM()
         if (session.isNull())
             return false;
 
-        /* Prepare console: */
-        CConsole console = session.GetConsole();
+        /* Prepare machine: */
+        CMachine machine = session.GetMachine();
 
         /* Take the snapshot: */
         QString strSnapshotName = tr("Linked Base for %1 and %2").arg(m_machine.GetName()).arg(strName);
-        CProgress progress = console.TakeSnapshot(strSnapshotName, "");
+        CProgress progress = machine.TakeSnapshot(strSnapshotName, "", true);
 
-        if (console.isOk())
+        if (machine.isOk())
         {
             /* Show the "Taking Snapshot" progress dialog: */
             msgCenter().showModalProgressDialog(progress, m_machine.GetName(), ":/progress_snapshot_create_90px.png", this);
@@ -98,7 +98,7 @@ bool UIWizardCloneVM::cloneVM()
         }
         else
         {
-            msgCenter().cannotTakeSnapshot(console, m_machine.GetName(), this);
+            msgCenter().cannotTakeSnapshot(machine, m_machine.GetName(), this);
             return false;
         }
 
diff --git a/src/VBox/GuestHost/OpenGL/error/error.py b/src/VBox/GuestHost/OpenGL/error/error.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py b/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py
old mode 100755
new mode 100644
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_current.py b/src/VBox/GuestHost/OpenGL/packer/pack_current.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_currentheader.py b/src/VBox/GuestHost/OpenGL/packer/pack_currentheader.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_header.py b/src/VBox/GuestHost/OpenGL/packer/pack_header.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/packer.py b/src/VBox/GuestHost/OpenGL/packer/packer.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/packer_bbox.py b/src/VBox/GuestHost/OpenGL/packer/packer_bbox.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/dispatch.py b/src/VBox/GuestHost/OpenGL/spu_loader/dispatch.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/dispatchheader.py b/src/VBox/GuestHost/OpenGL/spu_loader/dispatchheader.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py b/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py b/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/spucopy.py b/src/VBox/GuestHost/OpenGL/spu_loader/spucopy.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/convert.py b/src/VBox/GuestHost/OpenGL/state_tracker/convert.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/dump_gen.py b/src/VBox/GuestHost/OpenGL/state_tracker/dump_gen.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_current.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_current.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_defs.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_defs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
index eac707b..da25d8b 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
@@ -307,8 +307,6 @@ void crStateApplyFBImage(CRContext *to, CRFBData *data)
         for (i = 0; i < data->cElements; ++i)
         {
             CRFBDataElement *el = &data->aElements[i];
-            bool fUseRenderBuffer =
-                (el->enmFormat == GL_STENCIL_INDEX || el->enmFormat == GL_DEPTH_COMPONENT || el->enmFormat == GL_DEPTH_STENCIL);
 #if 0
             char fname[200];
             sprintf(fname, "./img_apply_%p_%d_%d.tga", to, i, el->enmFormat);
@@ -344,11 +342,7 @@ void crStateApplyFBImage(CRContext *to, CRFBData *data)
                 }
             }
 
-            /* Bind to corresponding buffer. */
-            if (fUseRenderBuffer)
-                diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, el->idFBO);
-            else
-                diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, el->idFBO);
+            diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, el->idFBO);
 
             if (el->enmBuffer)
                 diff_api.DrawBuffer(el->enmBuffer);
@@ -385,12 +379,6 @@ void crStateApplyFBImage(CRContext *to, CRFBData *data)
                 }
                 diff_api.Disable(GL_STENCIL_TEST);
             }
-
-            /* Bind to window system default buffer. */
-            if (fUseRenderBuffer)
-                diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
-            else
-                diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
         }
 
         diff_api.WindowPos3fvARB(to->current.rasterAttrib[VERT_ATTRIB_POS]);
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_funcs.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_funcs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_get.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_get.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_isenabled.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_isenabled.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/util/debug_opcodes.py b/src/VBox/GuestHost/OpenGL/util/debug_opcodes.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostDrivers/Support/SUPLibAll.cpp b/src/VBox/HostDrivers/Support/SUPLibAll.cpp
index a01c056..fa3f0ee 100644
--- a/src/VBox/HostDrivers/Support/SUPLibAll.cpp
+++ b/src/VBox/HostDrivers/Support/SUPLibAll.cpp
@@ -152,7 +152,7 @@ SUPDECL(uint64_t) SUPReadTscWithDelta(PSUPGLOBALINFOPAGE pGip)
     {
         int64_t iTscDelta = pGip->aCPUs[iGipCpu].i64TSCDelta;
         if (RT_LIKELY(iTscDelta != INT64_MAX))
-            return uTsc + iTscDelta;
+            return uTsc - iTscDelta;
 
 # ifdef IN_RING3
         /*
diff --git a/src/VBox/HostDrivers/Support/freebsd/Makefile b/src/VBox/HostDrivers/Support/freebsd/Makefile
index 236f9e9..278b3a4 100644
--- a/src/VBox/HostDrivers/Support/freebsd/Makefile
+++ b/src/VBox/HostDrivers/Support/freebsd/Makefile
@@ -82,6 +82,7 @@ SRCS += \
 	handletable.c \
 	handletablectx.c \
 	once.c \
+	term.c \
 	thread.c
 
 .PATH:	${.CURDIR}/common/string
@@ -89,6 +90,7 @@ SRCS += \
 	RTStrNCmp.c \
 	RTStrNLen.c \
 	RTStrCopy.c \
+	RTStrCopyEx.c \
 	RTStrCopyP.c \
 	strformat.c \
 	strformatrt.c \
@@ -172,6 +174,7 @@ SRCS += \
 SRCS += \
 	semspinmutex-r0drv-generic.c \
 	mpnotification-r0drv-generic.c \
+	threadctxhooks-r0drv-generic.c \
 	RTMpIsCpuWorkPending-r0drv-generic.c
 
 .PATH:	${.CURDIR}/VBox
diff --git a/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv b/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
index 1f48a4f..932e1a8 100755
--- a/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
+++ b/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
@@ -115,9 +115,11 @@ FILES_VBOXDRV_NOBIN=" \
     ${PATH_ROOT}/src/VBox/Runtime/common/misc/handletable.h=>common/misc/handletable.h \
     ${PATH_ROOT}/src/VBox/Runtime/common/misc/handletablectx.cpp=>common/misc/handletablectx.c \
     ${PATH_ROOT}/src/VBox/Runtime/common/misc/once.cpp=>common/misc/once.c \
+    ${PATH_ROOT}/src/VBox/Runtime/common/misc/term.cpp=>common/misc/term.c \
     ${PATH_ROOT}/src/VBox/Runtime/common/misc/thread.cpp=>common/misc/thread.c \
     ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
     ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopy.cpp=>common/string/RTStrCopy.c \
+    ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyEx.cpp=>common/string/RTStrCopyEx.c \
     ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNCmp.cpp=>common/string/RTStrNCmp.c \
     ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrNLen.cpp=>common/string/RTStrNLen.c \
     ${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/ndis6/VBoxNetLwf-win.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/ndis6/VBoxNetLwf-win.cpp
index 0c3d828..83b47e3 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/ndis6/VBoxNetLwf-win.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/ndis6/VBoxNetLwf-win.cpp
@@ -16,6 +16,7 @@
 #define LOG_GROUP LOG_GROUP_NET_FLT_DRV
 
 //#define VBOXNETLWF_SYNC_SEND
+#define VBOXNETLWF_NO_BYPASS
 
 #include <VBox/version.h>
 #include <VBox/err.h>
@@ -1417,6 +1418,17 @@ VOID vboxNetLwfWinSendNetBufferLists(IN NDIS_HANDLE hModuleCtx, IN PNET_BUFFER_L
     size_t cb = 0;
     LogFlow(("==>"__FUNCTION__": module=%p\n", hModuleCtx));
     PVBOXNETLWF_MODULE pModule = (PVBOXNETLWF_MODULE)hModuleCtx;
+#ifdef VBOXNETLWF_NO_BYPASS
+    if (!ASMAtomicReadBool(&pModule->fActive))
+    {
+        /*
+         * The trunk is inactive, jusp pass along all packets to the next
+         * underlying driver.
+         */
+        NdisFSendNetBufferLists(pModule->hFilter, pBufLists, nPort, fFlags);
+        return;
+    }
+#endif
     if (vboxNetLwfWinIsRunning(pModule))
     {
         PNET_BUFFER_LIST pNext     = NULL;
@@ -1541,6 +1553,17 @@ VOID vboxNetLwfWinReceiveNetBufferLists(IN NDIS_HANDLE hModuleCtx,
     /// @todo Do we need loopback handling?
     LogFlow(("==>"__FUNCTION__": module=%p\n", hModuleCtx));
     PVBOXNETLWF_MODULE pModule = (PVBOXNETLWF_MODULE)hModuleCtx;
+#ifdef VBOXNETLWF_NO_BYPASS
+    if (!ASMAtomicReadBool(&pModule->fActive))
+    {
+        /*
+         * The trunk is inactive, jusp pass along all packets to the next
+         * overlying driver.
+         */
+        NdisFIndicateReceiveNetBufferLists(pModule->hFilter, pBufLists, nPort, nBufLists, fFlags);
+        return;
+    }
+#endif
     if (vboxNetLwfWinIsRunning(pModule))
     {
         if (NDIS_TEST_RECEIVE_CANNOT_PEND(fFlags))
@@ -1698,7 +1721,9 @@ NDIS_STATUS vboxNetLwfWinSetModuleOptions(IN NDIS_HANDLE hModuleCtx)
     PChars.Header.Size = NDIS_SIZEOF_FILTER_PARTIAL_CHARACTERISTICS_REVISION_1;
     PChars.Header.Revision = NDIS_FILTER_PARTIAL_CHARACTERISTICS_REVISION_1;
 
+#ifndef VBOXNETLWF_NO_BYPASS
     if (ASMAtomicReadBool(&pModuleCtx->fActive))
+#endif
     {
         Log((__FUNCTION__": active mode\n"));
         PChars.SendNetBufferListsHandler = vboxNetLwfWinSendNetBufferLists;
@@ -1706,10 +1731,12 @@ NDIS_STATUS vboxNetLwfWinSetModuleOptions(IN NDIS_HANDLE hModuleCtx)
         PChars.ReceiveNetBufferListsHandler = vboxNetLwfWinReceiveNetBufferLists;
         PChars.ReturnNetBufferListsHandler = vboxNetLwfWinReturnNetBufferLists;
     }
+#ifndef VBOXNETLWF_NO_BYPASS
     else
     {
         Log((__FUNCTION__": bypass mode\n"));
     }
+#endif
     NDIS_STATUS Status = NdisSetOptionalHandlers(pModuleCtx->hFilter,
                                                  (PNDIS_DRIVER_OPTIONAL_HANDLERS)&PChars);
     LogFlow(("<=="__FUNCTION__": status=0x%x\n", Status));
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp
index 947833e..d332cbc 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp
@@ -187,13 +187,21 @@ VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u
     LARGE_INTEGER Interval;
     Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
     uint32_t cRefs;
+    size_t loops = 0; 
+    KTIMER kTimer;
+    NTSTATUS status = STATUS_SUCCESS;
 
-    while ((cRefs = ASMAtomicReadU32(&pRef->cRefs)) != u32Val)
+    KeInitializeTimer(&kTimer);
+    
+    while ((cRefs = ASMAtomicReadU32(&pRef->cRefs)) > u32Val && loops < 256)
     {
         Assert(cRefs >= u32Val);
         Assert(cRefs < UINT32_MAX/2);
 
-        KeDelayExecutionThread(KernelMode, FALSE, &Interval);
+        KeSetTimer(&kTimer, Interval, NULL);
+        status = KeWaitForSingleObject(&kTimer, Executive, KernelMode, false, NULL);
+        Assert(NT_SUCCESS(status));
+        loops++;
     }
 }
 
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h
index 57dcd88..764b01f 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h
@@ -189,16 +189,4 @@ static DECLINLINE(VOID) vboxUsbDdiStateReleaseAndWaitRemoved(PVBOXUSBDEV_EXT pDe
     VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 0);
 }
 
-static DECLHIDDEN(VOID) vboxUsbDdiStateWaitOtherCompleted(PVBOXUSBDEV_EXT pDevExt)
-{
-    /* Earlier we assumed that 1 request will be pending while we service
-       Device Power IRP which was leading to host hang when USB is connected
-       to VM.
-       With debugging found that at the point when host goes to sleep
-       state and USB is connected to VM,  two Power IRP requests are pending :
-       One for SYSTEM and other for DEVICE.
-    */
-    VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 3);
-}
-
 #endif /* #ifndef ___VBoxUsbDev_h___ */
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp
index 46dd412..7823280 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp
@@ -69,21 +69,15 @@ static NTSTATUS vboxUsbPnPMnCancelStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
 {
     ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
     NTSTATUS Status = STATUS_SUCCESS;
-    if (enmState == ENMVBOXUSB_PNPSTATE_STOP_PENDING)
-    {
-        IoCopyCurrentIrpStackLocationToNext(pIrp);
-        Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
-        if (NT_SUCCESS(Status))
-        {
-            vboxUsbPnPStateRestore(pDevExt);
-        }
-    }
-    else
+   
+    IoCopyCurrentIrpStackLocationToNext(pIrp);
+    Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
+    if (NT_SUCCESS(Status) && enmState == ENMVBOXUSB_PNPSTATE_STOP_PENDING)
     {
-        Assert(0);
-        Assert(enmState == ENMVBOXUSB_PNPSTATE_STARTED);
+        vboxUsbPnPStateRestore(pDevExt);
     }
-
+   
+    Status = STATUS_SUCCESS;
     VBoxDrvToolIoComplete(pIrp, Status, 0);
     vboxUsbDdiStateRelease(pDevExt);
 
@@ -143,21 +137,17 @@ static NTSTATUS vboxUsbPnPMnCancelRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIr
 {
     ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
     NTSTATUS Status = STATUS_SUCCESS;
-    if (enmState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING)
-    {
-        IoCopyCurrentIrpStackLocationToNext(pIrp);
-        Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
-        if (NT_SUCCESS(Status))
-        {
-            vboxUsbPnPStateRestore(pDevExt);
-        }
-    }
-    else
+    IoCopyCurrentIrpStackLocationToNext(pIrp);
+    
+    Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
+
+    if (NT_SUCCESS(Status) &&
+        enmState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING)
     {
-        Assert(0);
-        Assert(enmState == ENMVBOXUSB_PNPSTATE_STARTED);
+        vboxUsbPnPStateRestore(pDevExt);
     }
-
+    
+    Status = STATUS_SUCCESS;
     VBoxDrvToolIoComplete(pIrp, Status, 0);
     vboxUsbDdiStateRelease(pDevExt);
 
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp
index b0c8836..a3a0f1b 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPwr.cpp
@@ -209,8 +209,6 @@ static VOID vboxUsbPwrIoWaitCompletionAndPostAsyncWorker(IN PDEVICE_OBJECT pDevi
     PVBOXUSB_IOASYNC_CTX pCtx = (PVBOXUSB_IOASYNC_CTX)pvContext;
     PIRP pIrp = pCtx->pIrp;
 
-    vboxUsbDdiStateWaitOtherCompleted(pDevExt);
-
     vboxUsbPwrIoPostDev(pDevExt, pIrp);
 
     IoFreeWorkItem(pCtx->pWrkItem);
diff --git a/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp b/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp
index 1215090..760bb82 100644
--- a/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp
+++ b/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp
@@ -512,6 +512,7 @@ static SHFLROOT initWithWritableMapping(RTTEST hTest,
     AssertReleaseRC(VBoxHGCMSvcLoad(psvcTable));
     AssertRelease(  psvcTable->pvService
                   = RTTestGuardedAllocTail(hTest, psvcTable->cbClient));
+    RT_BZERO(psvcTable->pvService, psvcTable->cbClient);
     fillTestShflString(&FolderName, pcszFolderName);
     fillTestShflString(&Mapping, pcszMapping);
     aParms[0].setPointer(&FolderName,   RT_UOFFSETOF(SHFLSTRING, String)
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch_header.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch_header.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_get.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_get.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
index 299044d..e31e2ac 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
@@ -1362,11 +1362,12 @@ static int crVBoxServerFBImageDataInitEx(CRFBData *pData, CRContextInfo *pCtxInf
         return VINF_SUCCESS;
     }
 
+    /* Use GL_DEPTH_STENCIL only in case if both CR_STENCIL_BIT and CR_DEPTH_BIT specified. */
     if (   (pCtxInfo->CreateInfo.requestedVisualBits & CR_STENCIL_BIT)
-        || (pCtxInfo->CreateInfo.requestedVisualBits & CR_DEPTH_BIT))
+        && (pCtxInfo->CreateInfo.requestedVisualBits & CR_DEPTH_BIT))
     {
         pEl = &pData->aElements[pData->cElements];
-        pEl->idFBO = pMural->idDepthStencilRB;
+        pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
         pEl->enmBuffer = 0; /* we do not care */
         pEl->posX = 0;
         pEl->posY = 0;
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_retval.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_retval.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_simpleget.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_simpleget.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expando.py b/src/VBox/HostServices/SharedOpenGL/expando/expando.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_extend.py b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_extend.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_header.py b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_header.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Installer/common/virtualbox.desktop.in b/src/VBox/Installer/common/virtualbox.desktop.in
index e87bb7f..d73c05d 100644
--- a/src/VBox/Installer/common/virtualbox.desktop.in
+++ b/src/VBox/Installer/common/virtualbox.desktop.in
@@ -3,9 +3,12 @@ Encoding=UTF-8
 Version=1.0
 Name=@VBOX_PRODUCT@
 GenericName=Virtual Machine
+GenericName[de]=Virtuelle Maschine
 Type=Application
 Exec=VirtualBox %U
 TryExec=VirtualBox
+Keywords=virtualization
+Keywords[de]=Virtualisierung
 MimeType=application/x-virtualbox-vbox;application/x-virtualbox-vbox-extpack;application/x-virtualbox-ovf;application/x-virtualbox-ova;
 DocPath=file://@VBOX_DOC_PATH@/UserManual.pdf
 Icon=virtualbox
diff --git a/src/VBox/Installer/linux/distributions_deb b/src/VBox/Installer/linux/distributions_deb
index 9b8f346..9f5cc77 100644
--- a/src/VBox/Installer/linux/distributions_deb
+++ b/src/VBox/Installer/linux/distributions_deb
@@ -1,6 +1,8 @@
-_Debian_sid      = DEBIAN_7_0
+_Debian_sid      = DEBIAN_8_0
+_Debian_jessie   = DEBIAN_8_0
 _Debian_wheezy   = DEBIAN_7_0
 _Debian_squeeze  = DEBIAN_6_0
+_Ubuntu_trusty   = UBUNTU_14_04
 _Ubuntu_raring   = UBUNTU_13_04
 _Ubuntu_quantal  = UBUNTU_12_10
 _Ubuntu_precise  = UBUNTU_12_04
diff --git a/src/VBox/Installer/linux/vboxdrv-pardus.py b/src/VBox/Installer/linux/vboxdrv-pardus.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Installer/win/VirtualBox.wxs b/src/VBox/Installer/win/VirtualBox.wxs
index 95005f1..59645e7 100644
--- a/src/VBox/Installer/win/VirtualBox.wxs
+++ b/src/VBox/Installer/win/VirtualBox.wxs
@@ -107,6 +107,7 @@
         NOT VBOXINNOTEK
     </Condition>
 
+    
     <!-- *************************** Upgrade packages only ******************************* -->
     <!-- Minimum and Maximum specify the range of versions we are supposed to update with this upgrade.
          IncludeMaximum and IncludeMinimum specify whether the bound value is actually included in the range or not
@@ -163,6 +164,26 @@
     <CustomAction Id="ca_UninstallTAPInstances" BinaryKey="VBoxInstallHelper"
                   DllEntry="UninstallTAPInstances" Execute="deferred" Return="check" Impersonate="no"/>
 
+    <Property Id="VBOXDEPENDENCY" Secure="yes">
+        <DirectorySearch Id="VBoxInstallDir" Path="[EXISTINGINSTALLDIR]">
+            <FileSearch Name="dependency.dep"/>
+        </DirectorySearch>
+    </Property>
+    
+    <!--
+                            install upgrade uninstall
+    VBOXDEPENDENCY             0      1/0      1/0
+    UPGRADINGPRODUCTCODE       0       1        0
+    final                      0       1        0
+    not final                  1       0        1
+    -->
+
+    <Condition Message="It was detected an application which has been using currently installed VirtualBox version. 
+    You must remove this application before continuing installation. 
+    See the file dependency.dep in the VirtualBox installation directory for details. ">
+        NOT (VBOXDEPENDENCY AND UPGRADINGPRODUCTCODE)
+    </Condition>
+    
     <!-- Detect old Sun installation -->
     <!-- Force a manual uninstall of an already installed Sun VirtualBox version first -->
     <!--<Property Id="VBOXSUN">
diff --git a/src/VBox/Main/Makefile.kmk b/src/VBox/Main/Makefile.kmk
index dd56874..ef755b8 100644
--- a/src/VBox/Main/Makefile.kmk
+++ b/src/VBox/Main/Makefile.kmk
@@ -356,6 +356,7 @@ VBoxSVC_SOURCES = \
 	src-all/PCIDeviceAttachmentImpl.cpp \
 	src-all/ProgressImpl.cpp \
 	src-all/QMTranslatorImpl.cpp \
+	src-all/SecretKeyStore.cpp \
 	src-all/SharedFolderImpl.cpp \
 	src-all/AutoCaller.cpp \
 	src-all/VirtualBoxBase.cpp \
@@ -439,7 +440,8 @@ VBoxSVC_SOURCES.os2 = \
 	src-server/HostDnsServiceResolvConf.cpp
 
 VBoxSVC_SOURCES.freebsd = \
-	src-server/freebsd/HostHardwareFreeBSD.cpp
+	src-server/freebsd/HostHardwareFreeBSD.cpp \
+	src-server/HostDnsServiceResolvConf.cpp
 
 
 ifdef VBOX_WITH_USB
@@ -714,6 +716,7 @@ VBoxC_SOURCES = \
 	src-all/Logging.cpp \
 	src-all/PCIDeviceAttachmentImpl.cpp \
 	src-all/ProgressImpl.cpp \
+	src-all/SecretKeyStore.cpp \
 	src-all/SharedFolderImpl.cpp \
 	src-all/AutoCaller.cpp \
 	src-all/VirtualBoxBase.cpp \
diff --git a/src/VBox/Main/glue/vboxapi.py b/src/VBox/Main/glue/vboxapi.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Main/idl/VirtualBox.xidl b/src/VBox/Main/idl/VirtualBox.xidl
index 91f95ef..85e057c 100644
--- a/src/VBox/Main/idl/VirtualBox.xidl
+++ b/src/VBox/Main/idl/VirtualBox.xidl
@@ -586,7 +586,7 @@
 
   <enum
     name="MachineState"
-    uuid="ec6c6a9e-113d-4ff4-b44f-0b69f21c97fe"
+    uuid="87f085c3-ca67-4e45-9225-6057f32e9e8e"
     >
     <desc>
       Virtual machine execution state.
@@ -596,7 +596,7 @@
 
       Below is the basic virtual machine state diagram. It shows how the state
       changes during virtual machine execution. The text in square braces shows
-      a method of the IConsole interface that performs the given state
+      a method of the IConsole or IMachine interface that performs the given state
       transition.
 
       <pre>
@@ -610,7 +610,7 @@
     |     ^                                               | |                   | |
     |     |     +-----------------------------------------+-|-------------------+ +
     |     |     |                                           |                     |
-    |     |     +-- Saving <--------[takeSnapshot()]<-------+---------------------+
+    |     |     +- OnlineSnapshotting <--[takeSnapshot()]<--+---------------------+
     |     |                                                 |                     |
     |     +-------- Saving <--------[saveState()]<----------+---------------------+
     |                                                       |                     |
@@ -682,7 +682,7 @@
     +----------------------------------(same state as before the call)------+
     |                                                                       |
     +-> PoweredOff --+                                                      |
-    |                +-->[takeSnapshot()] -------------------> Saving ------+
+    |                +-->[takeSnapshot()] ------------------> Snapshotting -+
     +-> Aborted -----+
 
     +-> PoweredOff --+
@@ -694,13 +694,6 @@
     +---(Saved if restored from an online snapshot, PoweredOff otherwise)---+
       </pre>
 
-      Note that the Saving state is present in both the offline state group and
-      online state group. Currently, the only way to determine what group is
-      assumed in a particular case is to remember the previous machine state: if
-      it was Running or Paused, then Saving is an online state, otherwise it is
-      an offline state. This inconsistency may be removed in one of the future
-      versions of VirtualBox by adding a new state.
-
       <note internal="yes">
         For whoever decides to touch this enum: In order to keep the
         comparisons involving FirstOnline and LastOnline pseudo-states valid,
@@ -791,7 +784,7 @@
         A live snapshot is being taken. The machine is running normally, but
         some of the runtime configuration options are inaccessible. Also, if
         paused while in this state it will transition to
-        @c Saving and it will not be resume the
+        @c OnlineSnapshotting and it will not be resume the
         execution until the snapshot operation has completed.
       </desc>
     </const>
@@ -809,8 +802,7 @@
     </const>
     <const name="Saving"                    value="12">
       <desc>
-        Machine is saving its execution state to a file, or an online
-        snapshot of the machine is being taken.
+        Machine is saving its execution state to a file.
       </desc>
     </const>
     <const name="Restoring"                 value="13">
@@ -823,7 +815,7 @@
       <desc>
         The machine is being teleported to another host or process, but it is
         not running. This is the paused variant of the
-        @c state.
+        @c Teleporting state.
       </desc>
     </const>
     <const name="TeleportingIn"             value="15">
@@ -848,30 +840,41 @@
         merging of differencing media was started.
       </desc>
     </const>
-    <const name="RestoringSnapshot"         value="19">
+    <const name="OnlineSnapshotting"        value="19">
+      <desc>
+        Like @c LiveSnapshotting, but the machine was paused when the
+        merging of differencing media was started.
+      </desc>
+    </const>
+    <const name="RestoringSnapshot"         value="20">
       <desc>
         A machine snapshot is being restored; this typically does not take long.
       </desc>
     </const>
-    <const name="DeletingSnapshot"          value="20">
+    <const name="DeletingSnapshot"          value="21">
       <desc>
         A machine snapshot is being deleted; this can take a long time since this
         may require merging differencing media. This value indicates that the
         machine is not running while the snapshot is being deleted.
       </desc>
     </const>
-    <const name="SettingUp"                 value="21">
+    <const name="SettingUp"                 value="22">
       <desc>
         Lengthy setup operation is in progress.
       </desc>
     </const>
+    <const name="Snapshotting"              value="23">
+      <desc>
+        Taking an (offline) snapshot.
+      </desc>
+    </const>
 
     <const name="FirstOnline" value="5" wsmap="suppress"> <!-- Running -->
       <desc>
         Pseudo-state: first online state (for use in relational expressions).
       </desc>
     </const>
-    <const name="LastOnline" value="18" wsmap="suppress"> <!-- DeletingSnapshotPaused -->
+    <const name="LastOnline" value="19" wsmap="suppress"> <!-- OnlineSnapshotting -->
       <desc>
         Pseudo-state: last online state (for use in relational expressions).
       </desc>
@@ -882,7 +885,7 @@
         Pseudo-state: first transient state (for use in relational expressions).
       </desc>
     </const>
-    <const name="LastTransient" value="21" wsmap="suppress"> <!-- SettingUp -->
+    <const name="LastTransient" value="23" wsmap="suppress"> <!-- Snapshotting -->
       <desc>
         Pseudo-state: last transient state (for use in relational expressions).
       </desc>
@@ -1073,11 +1076,19 @@
 
   <enum
     name="LockType"
-    uuid="168a6a8e-12fd-4878-a1f9-38a750a56089"
+    uuid="678aaf14-2815-4c3e-b20a-e86ed0216498"
     >
     <desc>
       Used with <link to="IMachine::lockMachine" />.
     </desc>
+    <const name="Null" value="0">
+      <desc>Placeholder value, do not use when obtaining a lock.</desc>
+    </const>
+    <const name="Shared" value="1">
+      <desc>Request only a shared lock for remote-controlling the machine.
+        Such a lock allows changing certain VM settings which can be safely
+        modified for a running VM.</desc>
+    </const>
     <const name="Write" value="2">
       <desc>Lock the machine for writing. This requests an exclusive lock, i.e.
         there cannot be any other API client holding any type of lock for this
@@ -1085,11 +1096,6 @@
         which implicitly holds the equivalent of a shared lock during the
         entire VM runtime.</desc>
     </const>
-    <const name="Shared" value="1">
-      <desc>Request only a shared lock for remote-controlling the machine.
-        Such a lock allows changing certain VM settings which can be safely
-        modified for a running VM.</desc>
-    </const>
     <const name="VM" value="3">
       <desc>Lock the machine for writing, and create objects necessary for
         running a VM in this process.</desc>
@@ -2986,7 +2992,7 @@
 
   <interface
     name="IAppliance" extends="$unknown"
-    uuid="3059cf9e-25c7-4f0b-9fa5-3c42e441670b"
+    uuid="d9432012-2740-499f-b3b3-0991da3679f3"
     wsmap="managed"
     >
     <desc>
@@ -3242,6 +3248,32 @@
       </param>
     </method>
 
+    <method name="getPasswordIds">
+      <desc>
+        Returns a list of password identifiers which must be supplied to import or export
+        encrypted virtual machines.
+      </desc>
+
+      <param name="identifiers" type="wstring" dir="return" safearray="yes">
+        The list of password identifiers required on success.
+      </param>
+    </method>
+
+    <method name="addPasswords">
+      <desc>
+        Adds a list of passwords required to import or export encrypted virtual
+        machines.
+      </desc>
+
+      <param name="identifiers" type="wstring" dir="in" safearray="yes">
+        <desc>List of identifiers.</desc>
+      </param>
+
+      <param name="passwords" type="wstring" dir="in" safearray="yes">
+        <desc>List of matching passwords.</desc>
+      </param>
+    </method>
+
   </interface>
 
   <enum
@@ -3559,17 +3591,10 @@
 
   <interface
     name="IInternalMachineControl" extends="$unknown"
-    uuid="1470ff16-d7fa-448e-9c38-0352a36053bf"
+    uuid="f0b3bf6e-c609-4d5e-9fd7-77537a52c31b"
     internal="yes"
     wsmap="suppress"
     >
-    <method name="setRemoveSavedStateFile">
-      <desc>
-        Updates the flag whether the saved state file is removed on a
-        machine state change from Saved to PoweredOff.
-      </desc>
-      <param name="remove" type="boolean" dir="in"/>
-    </method>
 
     <method name="updateState">
       <desc>
@@ -3731,151 +3756,6 @@
       </param>
     </method>
 
-    <method name="beginSavingState">
-      <desc>
-        Called by the VM process to inform the server it wants to
-        save the current state and stop the VM execution.
-      </desc>
-      <param name="progress" type="IProgress" dir="out">
-        <desc>
-          Progress object created by VBoxSVC to wait until
-          the state is saved.
-        </desc>
-      </param>
-      <param name="stateFilePath" type="wstring" dir="out">
-        <desc>
-          File path the VM process must save the execution state to.
-        </desc>
-      </param>
-    </method>
-
-    <method name="endSavingState">
-      <desc>
-        Called by the VM process to inform the server that saving
-        the state previously requested by #beginSavingState is either
-        successfully finished or there was a failure.
-
-        <result name="VBOX_E_FILE_ERROR">
-          Settings file not accessible.
-        </result>
-        <result name="VBOX_E_XML_ERROR">
-          Could not parse the settings file.
-        </result>
-
-      </desc>
-
-      <param name="result" type="long" dir="in">
-        <desc>@c S_OK to indicate success.
-        </desc>
-      </param>
-      <param name="errMsg" type="wstring" dir="in">
-        <desc>@c human readable error message in case of failure.
-        </desc>
-      </param>
-    </method>
-
-    <method name="adoptSavedState">
-      <desc>
-        Gets called by <link to="IConsole::adoptSavedState"/>.
-        <result name="VBOX_E_FILE_ERROR">
-          Invalid saved state file path.
-        </result>
-      </desc>
-      <param name="savedStateFile" type="wstring" dir="in">
-        <desc>Path to the saved state file to adopt.</desc>
-      </param>
-    </method>
-
-    <method name="beginTakingSnapshot">
-      <desc>
-        Called from the VM process to request from the server to perform the
-        server-side actions of creating a snapshot (creating differencing images
-        and the snapshot object).
-
-        <result name="VBOX_E_FILE_ERROR">
-          Settings file not accessible.
-        </result>
-        <result name="VBOX_E_XML_ERROR">
-          Could not parse the settings file.
-        </result>
-      </desc>
-      <param name="initiator" type="IConsole" dir="in">
-        <desc>The console object that initiated this call.</desc>
-      </param>
-      <param name="name" type="wstring" dir="in">
-        <desc>Snapshot name.</desc>
-      </param>
-      <param name="description" type="wstring" dir="in">
-        <desc>Snapshot description.</desc>
-      </param>
-      <param name="consoleProgress" type="IProgress" dir="in">
-        <desc>
-          Progress object created by the VM process tracking the
-          snapshot's progress. This has the following sub-operations:
-          <ul>
-            <li>setting up (weight 1);</li>
-            <li>one for each medium attachment that needs a differencing image (weight 1 each);</li>
-            <li>another one to copy the VM state (if offline with saved state, weight is VM memory size in MB);</li>
-            <li>another one to save the VM state (if online, weight is VM memory size in MB);</li>
-            <li>finishing up (weight 1)</li>
-          </ul>
-        </desc>
-      </param>
-      <param name="fTakingSnapshotOnline" type="boolean" dir="in">
-        <desc>
-          Whether this is an online snapshot (i.e. the machine is running).
-        </desc>
-      </param>
-      <param name="stateFilePath" type="wstring" dir="out">
-        <desc>
-          File path the VM process must save the execution state to.
-        </desc>
-      </param>
-    </method>
-
-    <method name="endTakingSnapshot">
-      <desc>
-        Called by the VM process to inform the server that the snapshot
-        previously requested by #beginTakingSnapshot is either
-        successfully taken or there was a failure.
-      </desc>
-
-      <param name="success" type="boolean" dir="in">
-        <desc>@c true to indicate success and @c false otherwise</desc>
-      </param>
-    </method>
-
-    <method name="deleteSnapshot">
-      <desc>
-        Gets called by <link to="IConsole::deleteSnapshot"/>,
-        <link to="IConsole::deleteSnapshotAndAllChildren"/> and
-        <link to="IConsole::deleteSnapshotRange"/>.
-        <result name="VBOX_E_INVALID_OBJECT_STATE">
-          Snapshot has more than one child snapshot. Only possible if the
-          delete operation does not delete all children or the range does
-          not meet the linearity condition.
-        </result>
-      </desc>
-      <param name="initiator" type="IConsole" dir="in">
-        <desc>The console object that initiated this call.</desc>
-      </param>
-      <param name="startId" type="uuid" mod="string" dir="in">
-        <desc>UUID of the first snapshot to delete.</desc>
-      </param>
-      <param name="endId" type="uuid" mod="string" dir="in">
-        <desc>UUID of the last snapshot to delete.</desc>
-      </param>
-      <param name="deleteAllChildren" type="boolean" dir="in">
-        <desc>Whether all children should be deleted.</desc>
-      </param>
-      <param name="machineState" type="MachineState" dir="out">
-        <desc>New machine state after this operation is started.</desc>
-      </param>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
-      </param>
-    </method>
-
     <method name="finishOnlineMergeMedium">
       <desc>
         Gets called by <link to="IInternalSessionControl::onlineMergeMedium"/>.
@@ -3883,24 +3763,6 @@
       </desc>
     </method>
 
-    <method name="restoreSnapshot">
-      <desc>
-        Gets called by <link to="IConsole::restoreSnapshot"/>.
-      </desc>
-      <param name="initiator" type="IConsole" dir="in">
-        <desc>The console object that initiated this call.</desc>
-      </param>
-      <param name="snapshot" type="ISnapshot" dir="in">
-        <desc>The snapshot to restore the VM state from.</desc>
-      </param>
-      <param name="machineState" type="MachineState" dir="out">
-        <desc>New machine state after this operation is started.</desc>
-      </param>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
-      </param>
-    </method>
-
     <method name="pullGuestProperties">
       <desc>
         Get the list of the guest properties matching a set of patterns along
@@ -4314,7 +4176,7 @@
 
   <interface
     name="IMachine" extends="$unknown"
-    uuid="2280b3f8-0c33-4641-8bd5-ccecd1071b49"
+    uuid="bfe5287a-5fbc-4ceb-9f0e-7fb317e78681"
     wsmap="managed"
     wrap-hint-server-addinterfaces="IInternalMachineControl"
     wrap-hint-server="manualaddinterfaces"
@@ -4861,10 +4723,9 @@
       <desc>
         Current snapshot of this machine. This is @c null if the machine
         currently has no snapshots. If it is not @c null, then it was
-        set by one of <link to="IConsole::takeSnapshot" />,
-        <link to="IConsole::deleteSnapshot" />
-        or <link to="IConsole::restoreSnapshot" />, depending on which
-        was called last. See <link to="ISnapshot"/> for details.
+        set by one of <link to="#takeSnapshot" />, <link to="#deleteSnapshot" />
+        or <link to="#restoreSnapshot" />, depending on which was called last.
+       See <link to="ISnapshot"/> for details.
       </desc>
     </attribute>
 
@@ -4884,11 +4745,10 @@
         directly after one of the following calls are made:
 
         <ul>
-          <li><link to="IConsole::restoreSnapshot"/>
+          <li><link to="#restoreSnapshot"/>
           </li>
-          <li><link to="IConsole::takeSnapshot"/> (issued on a
-            "powered off" or "saved" machine, for which
-            <link to="#settingsModified"/> returns @c false)
+          <li><link to="#takeSnapshot"/> (issued on a "powered off" or "saved"
+            machine, for which <link to="#settingsModified"/> returns @c false)
           </li>
         </ul>
 
@@ -7405,67 +7265,390 @@
       </param>
     </method>
 
-  </interface>
+    <method name="saveState">
+      <desc>
+        Saves the current execution state of a running virtual machine
+        and stops its execution.
 
-  <interface
-    name="IEmulatedUSB" extends="$unknown"
-    uuid="38cc4dfd-8bb2-4d40-aebe-699eead8c2dd"
-    wsmap="managed"
-    >
-    <desc>
-      Manages emulated USB devices.
-    </desc>
+        After this operation completes, the machine will go to the
+        Saved state. Next time it is powered up, this state will
+        be restored and the machine will continue its execution from
+        the place where it was saved.
 
-    <method name="webcamAttach">
-      <desc>
-        Attaches the emulated USB webcam to the VM, which will use a host video capture device.
-      </desc>
-      <param name="path" type="wstring" dir="in">
-        <desc>The host path of the capture device to use.</desc>
-      </param>
-      <param name="settings" type="wstring" dir="in">
-        <desc>Optional settings.</desc>
-      </param>
-    </method>
+        This operation differs from taking a snapshot to the effect
+        that it doesn't create new differencing media. Also, once
+        the machine is powered up from the state saved using this method,
+        the saved state is deleted, so it will be impossible to return
+        to this state later.
 
-    <method name="webcamDetach">
-      <desc>
-        Detaches the emulated USB webcam from the VM
+        <note>
+          On success, this method implicitly calls
+          <link to="#saveSettings"/> to save all current machine
+          settings (including runtime changes to the DVD medium, etc.).
+          Together with the impossibility to change any VM settings when it is
+          in the Saved state, this guarantees adequate hardware
+          configuration of the machine when it is restored from the saved
+          state file.
+        </note>
+
+        <note>
+          The machine must be in the Running or Paused state, otherwise
+          the operation will fail.
+        </note>
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine state neither Running nor Paused.
+        </result>
+        <result name="VBOX_E_FILE_ERROR">
+          Failed to create directory for saved state file.
+        </result>
+
+        <see><link to="#takeSnapshot"/></see>
       </desc>
-      <param name="path" type="wstring" dir="in">
-        <desc>The host path of the capture device to detach.</desc>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
       </param>
     </method>
 
-    <attribute name="webcams" type="wstring" safearray="yes" readonly="yes">
-      <desc>Lists attached virtual webcams.</desc>
-    </attribute>
-  </interface>
+    <method name="adoptSavedState">
+      <desc>
+        Associates the given saved state file to the virtual machine.
 
-  <!--
-  // IConsole
-  /////////////////////////////////////////////////////////////////////////
-  -->
+        On success, the machine will go to the Saved state. Next time it is
+        powered up, it will be restored from the adopted saved state and
+        continue execution from the place where the saved state file was
+        created.
 
-  <interface
-    name="IVRDEServerInfo" extends="$unknown"
-    uuid="714434a1-58c3-4aab-9049-7652c5df113b"
-    wsmap="struct"
-    >
-    <desc>
-      Contains information about the remote desktop (VRDE) server capabilities and status.
-      This is used in the <link to="IConsole::VRDEServerInfo" /> attribute.
-    </desc>
+        The specified saved state file path may be absolute or relative to the
+        folder the VM normally saves the state to (usually,
+        <link to="#snapshotFolder"/>).
 
-    <attribute name="active" type="boolean" readonly="yes">
-      <desc>
-        Whether the remote desktop connection is active.
+        <note>
+          It's a caller's responsibility to make sure the given saved state
+          file is compatible with the settings of this virtual machine that
+          represent its virtual hardware (memory size, storage disk configuration
+          etc.). If there is a mismatch, the behavior of the virtual machine
+          is undefined.
+        </note>
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine state neither PoweredOff nor Aborted.
+        </result>
       </desc>
-    </attribute>
+      <param name="savedStateFile" type="wstring" dir="in">
+        <desc>Path to the saved state file to adopt.</desc>
+      </param>
+    </method>
 
-    <attribute name="port" type="long" readonly="yes">
+    <method name="discardSavedState">
       <desc>
-        VRDE server port number. If this property is equal to <tt>0</tt>, then
+        Forcibly resets the machine to "Powered Off" state if it is
+        currently in the "Saved" state (previously created by <link to="#saveState"/>).
+        Next time the machine is powered up, a clean boot will occur.
+        <note>
+          This operation is equivalent to resetting or powering off
+          the machine without doing a proper shutdown of the guest
+          operating system; as with resetting a running phyiscal
+          computer, it can can lead to data loss.
+        </note>
+        If @a fRemoveFile is @c true, the file in the machine directory
+        into which the machine state was saved is also deleted. If
+        this is @c false, then the state can be recovered and later
+        re-inserted into a machine using <link to="#adoptSavedState" />.
+        The location of the file can be found in the
+        <link to="#stateFilePath" /> attribute.
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine not in state Saved.
+        </result>
+      </desc>
+      <param name="fRemoveFile" type="boolean" dir="in" >
+        <desc>Whether to also remove the saved state file.</desc>
+      </param>
+    </method>
+
+    <method name="takeSnapshot">
+      <desc>
+        Saves the current execution state
+        and all settings of the machine and creates differencing images
+        for all normal (non-independent) media.
+        See <link to="ISnapshot" /> for an introduction to snapshots.
+
+        This method can be called for a PoweredOff, Saved (see
+        <link to="#saveState"/>), Running or
+        Paused virtual machine. When the machine is PoweredOff, an
+        offline snapshot is created. When the machine is Running a live
+        snapshot is created, and an online snapshot is created when Paused.
+
+        The taken snapshot is always based on the
+        <link to="#currentSnapshot">current snapshot</link>
+        of the associated virtual machine and becomes a new current snapshot.
+
+        <note>
+          This method implicitly calls <link to="#saveSettings"/> to
+          save all current machine settings before taking an offline snapshot.
+        </note>
+
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine currently changing state.
+        </result>
+      </desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Short name for the snapshot.</desc>
+      </param>
+      <param name="description" type="wstring" dir="in">
+        <desc>Optional description of the snapshot.</desc>
+      </param>
+      <param name="pause" type="boolean" dir="in">
+        <desc>Whether the VM should be paused while taking the snapshot. Only
+          relevant when the VM is running, and distinguishes between online
+          (@c true) and live (@c false) snapshots. When the VM is not running
+          the result is always an offline snapshot.</desc>
+      </param>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
+      </param>
+    </method>
+
+    <method name="deleteSnapshot">
+      <desc>
+        Starts deleting the specified snapshot asynchronously.
+        See <link to="ISnapshot" /> for an introduction to snapshots.
+
+        The execution state and settings of the associated machine stored in
+        the snapshot will be deleted. The contents of all differencing media of
+        this snapshot will be merged with the contents of their dependent child
+        media to keep the medium chain valid (in other words, all changes
+        represented by media being deleted will be propagated to their child
+        medium). After that, this snapshot's differencing medium will be
+        deleted. The parent of this snapshot will become a new parent for all
+        its child snapshots.
+
+        If the deleted snapshot is the current one, its parent snapshot will
+        become a new current snapshot. The current machine state is not directly
+        affected in this case, except that currently attached differencing
+        media based on media of the deleted snapshot will be also merged as
+        described above.
+
+        If the deleted snapshot is the first or current snapshot, then the
+        respective IMachine attributes will be adjusted. Deleting the current
+        snapshot will also implicitly call <link to="#saveSettings"/>
+        to make all current machine settings permanent.
+
+        Deleting a snapshot has the following preconditions:
+
+        <ul>
+          <li>Child media of all normal media of the deleted snapshot
+          must be accessible (see <link to="IMedium::state"/>) for this
+          operation to succeed. If only one running VM refers to all images
+          which participates in merging the operation can be performed while
+          the VM is running. Otherwise all virtual machines whose media are
+          directly or indirectly based on the media of deleted snapshot must
+          be powered off. In any case, online snapshot deleting usually is
+          slower than the same operation without any running VM.</li>
+
+          <li>You cannot delete the snapshot if a medium attached to it has
+          more than one child medium (differencing images) because otherwise
+          merging would be impossible. This might be the case if there is
+          more than one child snapshot or differencing images were created
+          for other reason (e.g. implicitly because of multiple machine
+          attachments).</li>
+        </ul>
+
+        The virtual machine's <link to="#state">state</link> is
+        changed to "DeletingSnapshot", "DeletingSnapshotOnline" or
+        "DeletingSnapshotPaused" while this operation is in progress.
+
+        <note>
+          Merging medium contents can be very time and disk space
+          consuming, if these media are big in size and have many
+          children. However, if the snapshot being deleted is the last
+          (head) snapshot on the branch, the operation will be rather
+          quick.
+        </note>
+        <result name="VBOX_E_INVALID_VM_STATE">
+          The running virtual machine prevents deleting this snapshot. This
+          happens only in very specific situations, usually snapshots can be
+          deleted without trouble while a VM is running. The error message
+          text explains the reason for the failure.
+        </result>
+      </desc>
+      <param name="id" type="uuid" mod="string" dir="in">
+        <desc>UUID of the snapshot to delete.</desc>
+      </param>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
+      </param>
+    </method>
+
+    <method name="deleteSnapshotAndAllChildren">
+      <desc>
+        Starts deleting the specified snapshot and all its children
+        asynchronously. See <link to="ISnapshot" /> for an introduction to
+        snapshots. The conditions and many details are the same as with
+        <link to="#deleteSnapshot"/>.
+
+        This operation is very fast if the snapshot subtree does not include
+        the current state. It is still significantly faster than deleting the
+        snapshots one by one if the current state is in the subtree and there
+        are more than one snapshots from current state to the snapshot which
+        marks the subtree, since it eliminates the incremental image merging.
+
+        <note>This API method is right now not implemented!</note>
+
+        <result name="VBOX_E_INVALID_VM_STATE">
+          The running virtual machine prevents deleting this snapshot. This
+          happens only in very specific situations, usually snapshots can be
+          deleted without trouble while a VM is running. The error message
+          text explains the reason for the failure.
+        </result>
+        <result name="E_NOTIMPL">
+          The method is not implemented yet.
+        </result>
+      </desc>
+      <param name="id" type="uuid" mod="string" dir="in">
+        <desc>UUID of the snapshot to delete, including all its children.</desc>
+      </param>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
+      </param>
+    </method>
+
+    <method name="deleteSnapshotRange">
+      <desc>
+        Starts deleting the specified snapshot range. This is limited to
+        linear snapshot lists, which means there may not be any other child
+        snapshots other than the direct sequence between the start and end
+        snapshot. If the start and end snapshot point to the same snapshot this
+        method is completely equivalent to <link to="#deleteSnapshot"/>. See
+        <link to="ISnapshot" /> for an introduction to snapshots. The
+        conditions and many details are the same as with
+        <link to="#deleteSnapshot"/>.
+
+        This operation is generally faster than deleting snapshots one by one
+        and often also needs less extra disk space before freeing up disk space
+        by deleting the removed disk images corresponding to the snapshot.
+
+        <note>This API method is right now not implemented!</note>
+
+        <result name="VBOX_E_INVALID_VM_STATE">
+          The running virtual machine prevents deleting this snapshot. This
+          happens only in very specific situations, usually snapshots can be
+          deleted without trouble while a VM is running. The error message
+          text explains the reason for the failure.
+        </result>
+        <result name="E_NOTIMPL">
+          The method is not implemented yet.
+        </result>
+      </desc>
+      <param name="startId" type="uuid" mod="string" dir="in">
+        <desc>UUID of the first snapshot to delete.</desc>
+      </param>
+      <param name="endId" type="uuid" mod="string" dir="in">
+        <desc>UUID of the last snapshot to delete.</desc>
+      </param>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
+      </param>
+    </method>
+
+    <method name="restoreSnapshot">
+      <desc>
+        Starts resetting the machine's current state to the state contained
+        in the given snapshot, asynchronously. All current settings of the
+        machine will be reset and changes stored in differencing media
+        will be lost.
+        See <link to="ISnapshot" /> for an introduction to snapshots.
+
+        After this operation is successfully completed, new empty differencing
+        media are created for all normal media of the machine.
+
+        If the given snapshot is an online snapshot, the machine will go to
+        the <link to="MachineState_Saved"> saved state</link>, so that the
+        next time it is powered on, the execution state will be restored
+        from the state of the snapshot.
+
+        <note>
+          The machine must not be running, otherwise the operation will fail.
+        </note>
+
+        <note>
+          If the machine state is <link to="MachineState_Saved">Saved</link>
+          prior to this operation, the saved state file will be implicitly
+          deleted (as if <link to="IMachine::discardSavedState"/> were
+          called).
+        </note>
+
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine is running.
+        </result>
+      </desc>
+      <param name="snapshot" type="ISnapshot" dir="in">
+        <desc>The snapshot to restore the VM state from.</desc>
+      </param>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
+      </param>
+    </method>
+
+  </interface>
+
+  <interface
+    name="IEmulatedUSB" extends="$unknown"
+    uuid="38cc4dfd-8bb2-4d40-aebe-699eead8c2dd"
+    wsmap="managed"
+    >
+    <desc>
+      Manages emulated USB devices.
+    </desc>
+
+    <method name="webcamAttach">
+      <desc>
+        Attaches the emulated USB webcam to the VM, which will use a host video capture device.
+      </desc>
+      <param name="path" type="wstring" dir="in">
+        <desc>The host path of the capture device to use.</desc>
+      </param>
+      <param name="settings" type="wstring" dir="in">
+        <desc>Optional settings.</desc>
+      </param>
+    </method>
+
+    <method name="webcamDetach">
+      <desc>
+        Detaches the emulated USB webcam from the VM
+      </desc>
+      <param name="path" type="wstring" dir="in">
+        <desc>The host path of the capture device to detach.</desc>
+      </param>
+    </method>
+
+    <attribute name="webcams" type="wstring" safearray="yes" readonly="yes">
+      <desc>Lists attached virtual webcams.</desc>
+    </attribute>
+  </interface>
+
+  <!--
+  // IConsole
+  /////////////////////////////////////////////////////////////////////////
+  -->
+
+  <interface
+    name="IVRDEServerInfo" extends="$unknown"
+    uuid="714434a1-58c3-4aab-9049-7652c5df113b"
+    wsmap="struct"
+    >
+    <desc>
+      Contains information about the remote desktop (VRDE) server capabilities and status.
+      This is used in the <link to="IConsole::VRDEServerInfo" /> attribute.
+    </desc>
+
+    <attribute name="active" type="boolean" readonly="yes">
+      <desc>
+        Whether the remote desktop connection is active.
+      </desc>
+    </attribute>
+
+    <attribute name="port" type="long" readonly="yes">
+      <desc>
+        VRDE server port number. If this property is equal to <tt>0</tt>, then
         the VRDE server failed to start, usually because there are no free IP
         ports to bind to. If this property is equal to <tt>-1</tt>, then the VRDE
         server has not yet been started.
@@ -7557,7 +7740,7 @@
 
   <interface
     name="IConsole" extends="$unknown"
-    uuid="080505f4-bca9-45aa-ab95-030036b665e6"
+    uuid="650b5f05-8258-4ee9-b518-89c515ca5dd9"
     wsmap="managed"
     >
     <desc>
@@ -7724,621 +7907,304 @@
         start from the beginning (as if the real hardware were just
         powered on).
 
-        If the machine is in the <link to="MachineState_Saved"/> state,
-        it will continue its execution the point where the state has
-        been saved.
-
-        If the machine <link to="IMachine::teleporterEnabled"/> property is
-        enabled on the machine being powered up, the machine will wait for an
-        incoming teleportation in the <link to="MachineState_TeleportingIn"/>
-        state. The returned progress object will have at least three
-        operations where the last three are defined as: (1) powering up and
-        starting TCP server, (2) waiting for incoming teleportations, and
-        (3) perform teleportation. These operations will be reflected as the
-        last three operations of the progress objected returned by
-        <link to="IMachine::launchVMProcess"/> as well.
-
-        <see><link to="#saveState"/></see>
-
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine already running.
-        </result>
-        <result name="VBOX_E_HOST_ERROR">
-          Host interface does not exist or name not set.
-        </result>
-        <result name="VBOX_E_FILE_ERROR">
-          Invalid saved state file.
-        </result>
-      </desc>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
-      </param>
-    </method>
-
-    <method name="powerUpPaused">
-      <desc>
-        Identical to powerUp except that the VM will enter the
-        <link to="MachineState_Paused"/> state, instead of
-        <link to="MachineState_Running"/>.
-
-        <see><link to="#powerUp"/></see>
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine already running.
-        </result>
-        <result name="VBOX_E_HOST_ERROR">
-          Host interface does not exist or name not set.
-        </result>
-        <result name="VBOX_E_FILE_ERROR">
-          Invalid saved state file.
-        </result>
-      </desc>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
-      </param>
-    </method>
-
-    <method name="powerDown">
-      <desc>
-        Initiates the power down procedure to stop the virtual machine
-        execution.
-
-        The completion of the power down procedure is tracked using the returned
-        IProgress object. After the operation is complete, the machine will go
-        to the PoweredOff state.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine must be Running, Paused or Stuck to be powered down.
-        </result>
-      </desc>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
-      </param>
-    </method>
-
-    <method name="reset">
-      <desc>Resets the virtual machine.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine not in Running state.
-        </result>
-        <result name="VBOX_E_VM_ERROR">
-          Virtual machine error in reset operation.
-        </result>
-      </desc>
-    </method>
-
-    <method name="pause">
-      <desc>Pauses the virtual machine execution.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine not in Running state.
-        </result>
-        <result name="VBOX_E_VM_ERROR">
-          Virtual machine error in suspend operation.
-        </result>
-      </desc>
-    </method>
-
-    <method name="resume">
-      <desc>Resumes the virtual machine execution.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine not in Paused state.
-        </result>
-        <result name="VBOX_E_VM_ERROR">
-          Virtual machine error in resume operation.
-        </result>
-      </desc>
-    </method>
-
-    <method name="powerButton">
-      <desc>Sends the ACPI power button event to the guest.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine not in Running state.
-        </result>
-        <result name="VBOX_E_PDM_ERROR">
-          Controlled power off failed.
-        </result>
-      </desc>
-    </method>
-
-    <method name="sleepButton">
-      <desc>Sends the ACPI sleep button event to the guest.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine not in Running state.
-        </result>
-        <result name="VBOX_E_PDM_ERROR">
-          Sending sleep button event failed.
-        </result>
-      </desc>
-    </method>
-
-    <method name="getPowerButtonHandled">
-      <desc>Checks if the last power button event was handled by guest.
-        <result name="VBOX_E_PDM_ERROR">
-          Checking if the event was handled by the guest OS failed.
-        </result>
-      </desc>
-      <param name="handled" type="boolean" dir="return"/>
-    </method>
-
-    <method name="getGuestEnteredACPIMode">
-      <desc>Checks if the guest entered the ACPI mode G0 (working) or
-        G1 (sleeping). If this method returns @c false, the guest will
-        most likely not respond to external ACPI events.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine not in Running state.
-        </result>
-      </desc>
-      <param name="entered" type="boolean" dir="return"/>
-    </method>
-
-    <method name="saveState">
-      <desc>
-        Saves the current execution state of a running virtual machine
-        and stops its execution.
-
-        After this operation completes, the machine will go to the
-        Saved state. Next time it is powered up, this state will
-        be restored and the machine will continue its execution from
-        the place where it was saved.
-
-        This operation differs from taking a snapshot to the effect
-        that it doesn't create new differencing media. Also, once
-        the machine is powered up from the state saved using this method,
-        the saved state is deleted, so it will be impossible to return
-        to this state later.
-
-        <note>
-          On success, this method implicitly calls
-          <link to="IMachine::saveSettings"/> to save all current machine
-          settings (including runtime changes to the DVD medium, etc.).
-          Together with the impossibility to change any VM settings when it is
-          in the Saved state, this guarantees adequate hardware
-          configuration of the machine when it is restored from the saved
-          state file.
-        </note>
-
-        <note>
-          The machine must be in the Running or Paused state, otherwise
-          the operation will fail.
-        </note>
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine state neither Running nor Paused.
-        </result>
-        <result name="VBOX_E_FILE_ERROR">
-          Failed to create directory for saved state file.
-        </result>
-
-        <see><link to="#takeSnapshot"/></see>
-      </desc>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
-      </param>
-    </method>
-
-    <method name="adoptSavedState">
-      <desc>
-        Associates the given saved state file to the virtual machine.
-
-        On success, the machine will go to the Saved state. Next time it is
-        powered up, it will be restored from the adopted saved state and
-        continue execution from the place where the saved state file was
-        created.
-
-        The specified saved state file path may be absolute or relative to the
-        folder the VM normally saves the state to (usually,
-        <link to="IMachine::snapshotFolder"/>).
-
-        <note>
-          It's a caller's responsibility to make sure the given saved state
-          file is compatible with the settings of this virtual machine that
-          represent its virtual hardware (memory size, storage disk configuration
-          etc.). If there is a mismatch, the behavior of the virtual machine
-          is undefined.
-        </note>
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine state neither PoweredOff nor Aborted.
-        </result>
-      </desc>
-      <param name="savedStateFile" type="wstring" dir="in">
-        <desc>Path to the saved state file to adopt.</desc>
-      </param>
-    </method>
-
-    <method name="discardSavedState">
-      <desc>
-        Forcibly resets the machine to "Powered Off" state if it is
-        currently in the "Saved" state (previously created by <link to="#saveState"/>).
-        Next time the machine is powered up, a clean boot will occur.
-        <note>
-          This operation is equivalent to resetting or powering off
-          the machine without doing a proper shutdown of the guest
-          operating system; as with resetting a running phyiscal
-          computer, it can can lead to data loss.
-        </note>
-        If @a fRemoveFile is @c true, the file in the machine directory
-        into which the machine state was saved is also deleted. If
-        this is @c false, then the state can be recovered and later
-        re-inserted into a machine using <link to="#adoptSavedState" />.
-        The location of the file can be found in the
-        <link to="IMachine::stateFilePath" /> attribute.
-        <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine not in state Saved.
-        </result>
-      </desc>
-      <param name="fRemoveFile" type="boolean" dir="in" >
-        <desc>Whether to also remove the saved state file.</desc>
-      </param>
-    </method>
-
-    <method name="getDeviceActivity">
-      <desc>
-        Gets the current activity type of given devices or device groups.
-        <result name="E_INVALIDARG">
-          Invalid device type.
-        </result>
-      </desc>
-      <param name="type" type="DeviceType" safearray="yes" dir="in"/>
-      <param name="activity" type="DeviceActivity" safearray="yes" dir="return"/>
-    </method>
-
-    <method name="attachUSBDevice">
-      <desc>
-        Attaches a host USB device with the given UUID to the
-        USB controller of the virtual machine.
-
-        The device needs to be in one of the following states:
-        <link to="USBDeviceState_Busy"/>,
-        <link to="USBDeviceState_Available"/> or
-        <link to="USBDeviceState_Held"/>,
-        otherwise an error is immediately returned.
+        If the machine is in the <link to="MachineState_Saved"/> state,
+        it will continue its execution the point where the state has
+        been saved.
 
-        When the device state is
-        <link to="USBDeviceState_Busy">Busy</link>, an error may also
-        be returned if the host computer refuses to release it for some reason.
+        If the machine <link to="IMachine::teleporterEnabled"/> property is
+        enabled on the machine being powered up, the machine will wait for an
+        incoming teleportation in the <link to="MachineState_TeleportingIn"/>
+        state. The returned progress object will have at least three
+        operations where the last three are defined as: (1) powering up and
+        starting TCP server, (2) waiting for incoming teleportations, and
+        (3) perform teleportation. These operations will be reflected as the
+        last three operations of the progress objected returned by
+        <link to="IMachine::launchVMProcess"/> as well.
+
+        <see><link to="IMachine::saveState"/></see>
 
-        <see><link to="IUSBDeviceFilters::deviceFilters"/>,
-          <link to="USBDeviceState"/></see>
         <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine state neither Running nor Paused.
+          Virtual machine already running.
         </result>
-        <result name="VBOX_E_PDM_ERROR">
-          Virtual machine does not have a USB controller.
+        <result name="VBOX_E_HOST_ERROR">
+          Host interface does not exist or name not set.
+        </result>
+        <result name="VBOX_E_FILE_ERROR">
+          Invalid saved state file.
         </result>
       </desc>
-      <param name="id" type="uuid" mod="string" dir="in">
-        <desc>UUID of the host USB device to attach.</desc>
-      </param>
-      <param name="captureFilename" type="wstring" dir="in">
-        <desc>Filename to capture the USB traffic to.</desc>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
       </param>
     </method>
 
-    <method name="detachUSBDevice">
+    <method name="powerUpPaused">
       <desc>
-        Detaches an USB device with the given UUID from the USB controller
-        of the virtual machine.
-
-        After this method succeeds, the VirtualBox server re-initiates
-        all USB filters as if the device were just physically attached
-        to the host, but filters of this machine are ignored to avoid
-        a possible automatic re-attachment.
-
-        <see><link to="IUSBDeviceFilters::deviceFilters"/>,
-          <link to="USBDeviceState"/></see>
+        Identical to powerUp except that the VM will enter the
+        <link to="MachineState_Paused"/> state, instead of
+        <link to="MachineState_Running"/>.
 
-        <result name="VBOX_E_PDM_ERROR">
-          Virtual machine does not have a USB controller.
+        <see><link to="#powerUp"/></see>
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine already running.
         </result>
-        <result name="E_INVALIDARG">
-          USB device not attached to this virtual machine.
+        <result name="VBOX_E_HOST_ERROR">
+          Host interface does not exist or name not set.
+        </result>
+        <result name="VBOX_E_FILE_ERROR">
+          Invalid saved state file.
         </result>
       </desc>
-      <param name="id" type="uuid" mod="string" dir="in">
-        <desc>UUID of the USB device to detach.</desc>
-      </param>
-      <param name="device" type="IUSBDevice" dir="return">
-        <desc>Detached USB device.</desc>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
       </param>
     </method>
 
-    <method name="findUSBDeviceByAddress">
+    <method name="powerDown">
       <desc>
-        Searches for a USB device with the given host address.
+        Initiates the power down procedure to stop the virtual machine
+        execution.
 
-        <result name="VBOX_E_OBJECT_NOT_FOUND">
-          Given @c name does not correspond to any USB device.
+        The completion of the power down procedure is tracked using the returned
+        IProgress object. After the operation is complete, the machine will go
+        to the PoweredOff state.
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine must be Running, Paused or Stuck to be powered down.
         </result>
-
-        <see><link to="IUSBDevice::address"/></see>
       </desc>
-      <param name="name" type="wstring" dir="in">
-        <desc>
-          Address of the USB device (as assigned by the host) to
-          search for.
-        </desc>
-      </param>
-      <param name="device" type="IUSBDevice" dir="return">
-        <desc>Found USB device object.</desc>
+      <param name="progress" type="IProgress" dir="return">
+        <desc>Progress object to track the operation completion.</desc>
       </param>
     </method>
 
-    <method name="findUSBDeviceById">
-      <desc>
-        Searches for a USB device with the given UUID.
-
-        <result name="VBOX_E_OBJECT_NOT_FOUND">
-          Given @c id does not correspond to any USB device.
+    <method name="reset">
+      <desc>Resets the virtual machine.
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine not in Running state.
+        </result>
+        <result name="VBOX_E_VM_ERROR">
+          Virtual machine error in reset operation.
         </result>
-
-        <see><link to="IUSBDevice::id"/></see>
       </desc>
-      <param name="id" type="uuid" mod="string" dir="in">
-        <desc>UUID of the USB device to search for.</desc>
-      </param>
-      <param name="device" type="IUSBDevice" dir="return">
-        <desc>Found USB device object.</desc>
-      </param>
     </method>
 
-    <method name="createSharedFolder">
-      <desc>
-        Creates a transient new shared folder by associating the given logical
-        name with the given host path, adds it to the collection of shared
-        folders and starts sharing it. Refer to the description of
-        <link to="ISharedFolder"/> to read more about logical names.
-
+    <method name="pause">
+      <desc>Pauses the virtual machine execution.
         <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine in Saved state or currently changing state.
+          Virtual machine not in Running state.
         </result>
-        <result name="VBOX_E_FILE_ERROR">
-          Shared folder already exists or not accessible.
+        <result name="VBOX_E_VM_ERROR">
+          Virtual machine error in suspend operation.
         </result>
       </desc>
-      <param name="name" type="wstring" dir="in">
-        <desc>Unique logical name of the shared folder.</desc>
-      </param>
-      <param name="hostPath" type="wstring" dir="in">
-        <desc>Full path to the shared folder in the host file system.</desc>
-      </param>
-      <param name="writable" type="boolean" dir="in">
-        <desc>Whether the share is writable or readonly</desc>
-      </param>
-      <param name="automount" type="boolean" dir="in">
-        <desc>Whether the share gets automatically mounted by the guest
-          or not.</desc>
-      </param>
     </method>
 
-    <method name="removeSharedFolder">
-      <desc>
-        Removes a transient shared folder with the given name previously
-        created by <link to="#createSharedFolder"/> from the collection of
-        shared folders and stops sharing it.
+    <method name="resume">
+      <desc>Resumes the virtual machine execution.
         <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine in Saved state or currently changing state.
+          Virtual machine not in Paused state.
         </result>
-        <result name="VBOX_E_FILE_ERROR">
-          Shared folder does not exists.
+        <result name="VBOX_E_VM_ERROR">
+          Virtual machine error in resume operation.
         </result>
       </desc>
-      <param name="name" type="wstring" dir="in">
-        <desc>Logical name of the shared folder to remove.</desc>
-      </param>
     </method>
 
-    <method name="takeSnapshot">
-      <desc>
-        Saves the current execution state
-        and all settings of the machine and creates differencing images
-        for all normal (non-independent) media.
-        See <link to="ISnapshot" /> for an introduction to snapshots.
-
-        This method can be called for a PoweredOff, Saved (see
-        <link to="#saveState"/>), Running or
-        Paused virtual machine. When the machine is PoweredOff, an
-        offline snapshot is created. When the machine is Running a live
-        snapshot is created, and an online snapshot is created when Paused.
+    <method name="powerButton">
+      <desc>Sends the ACPI power button event to the guest.
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine not in Running state.
+        </result>
+        <result name="VBOX_E_PDM_ERROR">
+          Controlled power off failed.
+        </result>
+      </desc>
+    </method>
 
-        The taken snapshot is always based on the
-        <link to="IMachine::currentSnapshot">current snapshot</link>
-        of the associated virtual machine and becomes a new current snapshot.
+    <method name="sleepButton">
+      <desc>Sends the ACPI sleep button event to the guest.
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine not in Running state.
+        </result>
+        <result name="VBOX_E_PDM_ERROR">
+          Sending sleep button event failed.
+        </result>
+      </desc>
+    </method>
 
-        <note>
-          This method implicitly calls <link to="IMachine::saveSettings"/> to
-          save all current machine settings before taking an offline snapshot.
-        </note>
+    <method name="getPowerButtonHandled">
+      <desc>Checks if the last power button event was handled by guest.
+        <result name="VBOX_E_PDM_ERROR">
+          Checking if the event was handled by the guest OS failed.
+        </result>
+      </desc>
+      <param name="handled" type="boolean" dir="return"/>
+    </method>
 
+    <method name="getGuestEnteredACPIMode">
+      <desc>Checks if the guest entered the ACPI mode G0 (working) or
+        G1 (sleeping). If this method returns @c false, the guest will
+        most likely not respond to external ACPI events.
         <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine currently changing state.
+          Virtual machine not in Running state.
         </result>
       </desc>
-      <param name="name" type="wstring" dir="in">
-        <desc>Short name for the snapshot.</desc>
-      </param>
-      <param name="description" type="wstring" dir="in">
-        <desc>Optional description of the snapshot.</desc>
-      </param>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
-      </param>
+      <param name="entered" type="boolean" dir="return"/>
     </method>
 
-    <method name="deleteSnapshot">
+    <method name="getDeviceActivity">
       <desc>
-        Starts deleting the specified snapshot asynchronously.
-        See <link to="ISnapshot" /> for an introduction to snapshots.
-
-        The execution state and settings of the associated machine stored in
-        the snapshot will be deleted. The contents of all differencing media of
-        this snapshot will be merged with the contents of their dependent child
-        media to keep the medium chain valid (in other words, all changes
-        represented by media being deleted will be propagated to their child
-        medium). After that, this snapshot's differencing medium will be
-        deleted. The parent of this snapshot will become a new parent for all
-        its child snapshots.
-
-        If the deleted snapshot is the current one, its parent snapshot will
-        become a new current snapshot. The current machine state is not directly
-        affected in this case, except that currently attached differencing
-        media based on media of the deleted snapshot will be also merged as
-        described above.
-
-        If the deleted snapshot is the first or current snapshot, then the
-        respective IMachine attributes will be adjusted. Deleting the current
-        snapshot will also implicitly call <link to="IMachine::saveSettings"/>
-        to make all current machine settings permanent.
-
-        Deleting a snapshot has the following preconditions:
+        Gets the current activity type of given devices or device groups.
+        <result name="E_INVALIDARG">
+          Invalid device type.
+        </result>
+      </desc>
+      <param name="type" type="DeviceType" safearray="yes" dir="in"/>
+      <param name="activity" type="DeviceActivity" safearray="yes" dir="return"/>
+    </method>
 
-        <ul>
-          <li>Child media of all normal media of the deleted snapshot
-          must be accessible (see <link to="IMedium::state"/>) for this
-          operation to succeed. If only one running VM refers to all images
-          which participates in merging the operation can be performed while
-          the VM is running. Otherwise all virtual machines whose media are
-          directly or indirectly based on the media of deleted snapshot must
-          be powered off. In any case, online snapshot deleting usually is
-          slower than the same operation without any running VM.</li>
+    <method name="attachUSBDevice">
+      <desc>
+        Attaches a host USB device with the given UUID to the
+        USB controller of the virtual machine.
 
-          <li>You cannot delete the snapshot if a medium attached to it has
-          more than one child medium (differencing images) because otherwise
-          merging would be impossible. This might be the case if there is
-          more than one child snapshot or differencing images were created
-          for other reason (e.g. implicitly because of multiple machine
-          attachments).</li>
-        </ul>
+        The device needs to be in one of the following states:
+        <link to="USBDeviceState_Busy"/>,
+        <link to="USBDeviceState_Available"/> or
+        <link to="USBDeviceState_Held"/>,
+        otherwise an error is immediately returned.
 
-        The virtual machine's <link to="IMachine::state">state</link> is
-        changed to "DeletingSnapshot", "DeletingSnapshotOnline" or
-        "DeletingSnapshotPaused" while this operation is in progress.
+        When the device state is
+        <link to="USBDeviceState_Busy">Busy</link>, an error may also
+        be returned if the host computer refuses to release it for some reason.
 
-        <note>
-          Merging medium contents can be very time and disk space
-          consuming, if these media are big in size and have many
-          children. However, if the snapshot being deleted is the last
-          (head) snapshot on the branch, the operation will be rather
-          quick.
-        </note>
+        <see><link to="IUSBDeviceFilters::deviceFilters"/>,
+          <link to="USBDeviceState"/></see>
         <result name="VBOX_E_INVALID_VM_STATE">
-          The running virtual machine prevents deleting this snapshot. This
-          happens only in very specific situations, usually snapshots can be
-          deleted without trouble while a VM is running. The error message
-          text explains the reason for the failure.
+          Virtual machine state neither Running nor Paused.
+        </result>
+        <result name="VBOX_E_PDM_ERROR">
+          Virtual machine does not have a USB controller.
         </result>
       </desc>
       <param name="id" type="uuid" mod="string" dir="in">
-        <desc>UUID of the snapshot to delete.</desc>
+        <desc>UUID of the host USB device to attach.</desc>
       </param>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
+      <param name="captureFilename" type="wstring" dir="in">
+        <desc>Filename to capture the USB traffic to.</desc>
       </param>
     </method>
 
-    <method name="deleteSnapshotAndAllChildren">
+    <method name="detachUSBDevice">
       <desc>
-        Starts deleting the specified snapshot and all its children
-        asynchronously. See <link to="ISnapshot" /> for an introduction to
-        snapshots. The conditions and many details are the same as with
-        <link to="#deleteSnapshot"/>.
+        Detaches an USB device with the given UUID from the USB controller
+        of the virtual machine.
 
-        This operation is very fast if the snapshot subtree does not include
-        the current state. It is still significantly faster than deleting the
-        snapshots one by one if the current state is in the subtree and there
-        are more than one snapshots from current state to the snapshot which
-        marks the subtree, since it eliminates the incremental image merging.
+        After this method succeeds, the VirtualBox server re-initiates
+        all USB filters as if the device were just physically attached
+        to the host, but filters of this machine are ignored to avoid
+        a possible automatic re-attachment.
 
-        <note>This API method is right now not implemented!</note>
+        <see><link to="IUSBDeviceFilters::deviceFilters"/>,
+          <link to="USBDeviceState"/></see>
 
-        <result name="VBOX_E_INVALID_VM_STATE">
-          The running virtual machine prevents deleting this snapshot. This
-          happens only in very specific situations, usually snapshots can be
-          deleted without trouble while a VM is running. The error message
-          text explains the reason for the failure.
+        <result name="VBOX_E_PDM_ERROR">
+          Virtual machine does not have a USB controller.
         </result>
-        <result name="E_NOTIMPL">
-          The method is not implemented yet.
+        <result name="E_INVALIDARG">
+          USB device not attached to this virtual machine.
         </result>
       </desc>
       <param name="id" type="uuid" mod="string" dir="in">
-        <desc>UUID of the snapshot to delete, including all its children.</desc>
+        <desc>UUID of the USB device to detach.</desc>
       </param>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
+      <param name="device" type="IUSBDevice" dir="return">
+        <desc>Detached USB device.</desc>
       </param>
     </method>
 
-    <method name="deleteSnapshotRange">
+    <method name="findUSBDeviceByAddress">
       <desc>
-        Starts deleting the specified snapshot range. This is limited to
-        linear snapshot lists, which means there may not be any other child
-        snapshots other than the direct sequence between the start and end
-        snapshot. If the start and end snapshot point to the same snapshot this
-        method is completely equivalent to <link to="#deleteSnapshot"/>. See
-        <link to="ISnapshot" /> for an introduction to snapshots. The
-        conditions and many details are the same as with
-        <link to="#deleteSnapshot"/>.
-
-        This operation is generally faster than deleting snapshots one by one
-        and often also needs less extra disk space before freeing up disk space
-        by deleting the removed disk images corresponding to the snapshot.
-
-        <note>This API method is right now not implemented!</note>
+        Searches for a USB device with the given host address.
 
-        <result name="VBOX_E_INVALID_VM_STATE">
-          The running virtual machine prevents deleting this snapshot. This
-          happens only in very specific situations, usually snapshots can be
-          deleted without trouble while a VM is running. The error message
-          text explains the reason for the failure.
-        </result>
-        <result name="E_NOTIMPL">
-          The method is not implemented yet.
+        <result name="VBOX_E_OBJECT_NOT_FOUND">
+          Given @c name does not correspond to any USB device.
         </result>
+
+        <see><link to="IUSBDevice::address"/></see>
       </desc>
-      <param name="startId" type="uuid" mod="string" dir="in">
-        <desc>UUID of the first snapshot to delete.</desc>
-      </param>
-      <param name="endId" type="uuid" mod="string" dir="in">
-        <desc>UUID of the last snapshot to delete.</desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>
+          Address of the USB device (as assigned by the host) to
+          search for.
+        </desc>
       </param>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
+      <param name="device" type="IUSBDevice" dir="return">
+        <desc>Found USB device object.</desc>
       </param>
     </method>
 
-    <method name="restoreSnapshot">
+    <method name="findUSBDeviceById">
       <desc>
-        Starts resetting the machine's current state to the state contained
-        in the given snapshot, asynchronously. All current settings of the
-        machine will be reset and changes stored in differencing media
-        will be lost.
-        See <link to="ISnapshot" /> for an introduction to snapshots.
-
-        After this operation is successfully completed, new empty differencing
-        media are created for all normal media of the machine.
+        Searches for a USB device with the given UUID.
 
-        If the given snapshot is an online snapshot, the machine will go to
-        the <link to="MachineState_Saved"> saved state</link>, so that the
-        next time it is powered on, the execution state will be restored
-        from the state of the snapshot.
+        <result name="VBOX_E_OBJECT_NOT_FOUND">
+          Given @c id does not correspond to any USB device.
+        </result>
 
-        <note>
-          The machine must not be running, otherwise the operation will fail.
-        </note>
+        <see><link to="IUSBDevice::id"/></see>
+      </desc>
+      <param name="id" type="uuid" mod="string" dir="in">
+        <desc>UUID of the USB device to search for.</desc>
+      </param>
+      <param name="device" type="IUSBDevice" dir="return">
+        <desc>Found USB device object.</desc>
+      </param>
+    </method>
 
-        <note>
-          If the machine state is <link to="MachineState_Saved">Saved</link>
-          prior to this operation, the saved state file will be implicitly
-          deleted (as if <link to="IConsole::discardSavedState"/> were
-          called).
-        </note>
+    <method name="createSharedFolder">
+      <desc>
+        Creates a transient new shared folder by associating the given logical
+        name with the given host path, adds it to the collection of shared
+        folders and starts sharing it. Refer to the description of
+        <link to="ISharedFolder"/> to read more about logical names.
 
         <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine is running.
+          Virtual machine in Saved state or currently changing state.
+        </result>
+        <result name="VBOX_E_FILE_ERROR">
+          Shared folder already exists or not accessible.
         </result>
       </desc>
-      <param name="snapshot" type="ISnapshot" dir="in">
-        <desc>The snapshot to restore the VM state from.</desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Unique logical name of the shared folder.</desc>
       </param>
-      <param name="progress" type="IProgress" dir="return">
-        <desc>Progress object to track the operation completion.</desc>
+      <param name="hostPath" type="wstring" dir="in">
+        <desc>Full path to the shared folder in the host file system.</desc>
+      </param>
+      <param name="writable" type="boolean" dir="in">
+        <desc>Whether the share is writable or readonly</desc>
+      </param>
+      <param name="automount" type="boolean" dir="in">
+        <desc>Whether the share gets automatically mounted by the guest
+          or not.</desc>
+      </param>
+    </method>
+
+    <method name="removeSharedFolder">
+      <desc>
+        Removes a transient shared folder with the given name previously
+        created by <link to="#createSharedFolder"/> from the collection of
+        shared folders and stops sharing it.
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Virtual machine in Saved state or currently changing state.
+        </result>
+        <result name="VBOX_E_FILE_ERROR">
+          Shared folder does not exists.
+        </result>
+      </desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Logical name of the shared folder to remove.</desc>
       </param>
     </method>
 
@@ -12710,7 +12576,7 @@
         An instance of this is returned every time VirtualBox starts
         an asynchronous task (in other words, a separate thread) which
         continues to run after a method call returns. For example,
-        <link to="IConsole::saveState" />, which saves the state of
+        <link to="IMachine::saveState" />, which saves the state of
         a running virtual machine, can take a long time to complete.
         To be able to display a progress bar, a user interface such as
         the VirtualBox graphical user interface can use the IProgress
@@ -12959,12 +12825,12 @@
       the exact state it was in when the snapshot was taken.
 
       The ISnapshot interface has no methods, only attributes; snapshots
-      are controlled through methods of the <link to="IConsole" /> interface
+      are controlled through methods of the <link to="IMachine" /> interface
       which also manage the media associated with the snapshot.
       The following operations exist:
 
       <ul>
-          <li><link to="IConsole::takeSnapshot"/> creates a new snapshot
+          <li><link to="IMachine::takeSnapshot"/> creates a new snapshot
               by creating new, empty differencing images for the machine's
               media and saving the VM settings and (if the VM is running)
               the current VM state in the snapshot.
@@ -12982,7 +12848,7 @@
               snapshots tree.
           </li>
 
-          <li><link to="IConsole::restoreSnapshot"/> resets a machine to
+          <li><link to="IMachine::restoreSnapshot"/> resets a machine to
               the state of a previous snapshot by deleting the differencing
               image of each of the machine's media and setting the machine's
               settings and state to the state that was saved in the snapshot (if any).
@@ -12992,7 +12858,7 @@
               that was restored.
           </li>
 
-          <li><link to="IConsole::deleteSnapshot"/> deletes a snapshot
+          <li><link to="IMachine::deleteSnapshot"/> deletes a snapshot
               without affecting the current machine state.
 
               This does not change the current machine state, but instead frees the
@@ -15937,7 +15803,7 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
 
   <interface
     name="IDisplay" extends="$unknown"
-    uuid="04AA5E91-3816-4990-8C52-59939307E5EF"
+    uuid="94a7faa2-7792-42a3-8535-00770eca1f53"
     wsmap="managed"
     wrap-hint-server-addinterfaces="IEventListener"
     >
@@ -15977,6 +15843,7 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
       </desc>
       <param name="screenId" type="unsigned long" dir="in"/>
       <param name="framebuffer" type="IFramebuffer" dir="in"/>
+      <param name="id" type="uuid" mod="string" dir="return"/>
     </method>
 
     <method name="detachFramebuffer">
@@ -15984,6 +15851,7 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
         Removes the graphics updates target for a screen.
       </desc>
       <param name="screenId" type="unsigned long" dir="in"/>
+      <param name="id" type="uuid" mod="string" dir="in"/>
     </method>
 
     <method name="queryFramebuffer">
@@ -16550,7 +16418,7 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
 
   <enum
     name="PortMode"
-    uuid="533b5fe3-0185-4197-86a7-17e37dd39d76"
+    uuid="7485fcfd-d603-470a-87af-26d33beb7de9"
     >
     <desc>
       The PortMode enumeration represents possible communication modes for
@@ -16569,6 +16437,9 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
     <const name="RawFile"           value="3">
       <desc>Virtual device is attached to a raw file.</desc>
     </const>
+    <const name="TCP"               value="4">
+      <desc>Virtual device is attached to a TCP socket.</desc>
+    </const>
   </enum>
 
   <interface
@@ -16638,17 +16509,19 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
       <desc>
         Flag whether this serial port acts as a server (creates a new pipe on
         the host) or as a client (uses the existing pipe). This attribute is
-        used only when <link to="#hostMode"/> is PortMode_HostPipe.
+        used only when <link to="#hostMode"/> is PortMode_HostPipe or PortMode_TCP.
       </desc>
     </attribute>
 
     <attribute name="path" type="wstring">
       <desc>
         Path to the serial port's pipe on the host when <link to="ISerialPort::hostMode"/> is
-        PortMode_HostPipe, or the host serial device name when
-        <link to="ISerialPort::hostMode"/> is PortMode_HostDevice. For both
-        cases, setting a @c null or empty string as the attribute's value
-        is an error. Otherwise, the value of this property is ignored.
+        PortMode_HostPipe, the host serial device name when
+        <link to="ISerialPort::hostMode"/> is PortMode_HostDevice or the TCP
+       <b>port</b> (server) or <b>hostname:port</b> (client) when
+        <link to="ISerialPort::hostMode"/> is PortMode_TCP.
+        For those cases, setting a @c null or empty string as the attribute's
+        value is an error. Otherwise, the value of this property is ignored.
       </desc>
     </attribute>
 
@@ -18163,21 +18036,23 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
     <const name="HostBatteryLow"    value="3">
       <desc>Host is running low on battery (power management event).</desc>
     </const>
+    <const name="Snapshot"          value="4">
+      <desc>A snapshot of the VM is being taken.</desc>
+    </const>
   </enum>
 
   <interface
     name="IInternalSessionControl" extends="$unknown"
-    uuid="fdb5fa71-eddb-4e06-9844-277d22270fe0"
+    uuid="747e397e-69c8-45a0-88d9-f7f070960718"
     internal="yes"
     wsmap="suppress"
     >
-    <method name="getPID">
+    <attribute name="PID" type="unsigned long" readonly="yes">
       <desc>PID of the process that has created this Session object.
       </desc>
-      <param name="pid" type="unsigned long" dir="return"/>
-    </method>
+    </attribute>
 
-    <method name="getRemoteConsole">
+    <attribute name="remoteConsole" type="IConsole" readonly="yes">
       <desc>
         Returns the console object suitable for remote control.
 
@@ -18189,8 +18064,14 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
         </result>
 
       </desc>
-      <param name="console" type="IConsole" dir="return"/>
-    </method>
+    </attribute>
+
+    <attribute name="nominalState" type="MachineState" readonly="yes">
+      <desc>Returns suitable machine state for the VM execution state. Useful
+        for choosing a sensible machine state after a complex operation which
+        failed or otherwise resulted in an unclear situation.
+      </desc>
+    </attribute>
 
 <if target="midl">
     <method name="assignMachine">
@@ -18659,6 +18540,24 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
       </param>
     </method>
 
+    <method name="reconfigureMediumAttachments">
+      <desc>
+        Reconfigure all specified medium attachments in one go, making sure
+        the current state corresponds to the specified medium.
+
+        <result name="VBOX_E_INVALID_VM_STATE">
+          Machine session is not open.
+        </result>
+        <result name="VBOX_E_INVALID_OBJECT_STATE">
+          Session type is not direct.
+        </result>
+      </desc>
+      <param name="attachments" type="IMediumAttachment" dir="in" safearray="yes">
+        <desc>Array containing the medium attachments which need to be
+          reconfigured.</desc>
+      </param>
+    </method>
+
     <method name="enableVMMStatistics">
       <desc>
         Enables or disables collection of VMM RAM statistics.
@@ -18722,21 +18621,43 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
         code. The reason code can be interpreted by device/drivers and thus it
         might behave slightly differently than a normal VM save state.
 
+        This call is fully synchronous, and the caller is expected to have set
+        the machine state appropriately (and has to set the follow-up machine
+        state if this call failed).
+
         <result name="VBOX_E_INVALID_VM_STATE">
-          Virtual machine state neither Running nor Paused.
+          Virtual machine state is not one of the expected values.
         </result>
         <result name="VBOX_E_FILE_ERROR">
           Failed to create directory for saved state file.
         </result>
-        <see><link to="IConsole::saveState"/></see>
+        <see><link to="IMachine::saveState"/></see>
       </desc>
 
       <param name="reason" type="Reason" dir="in">
         <desc>Specify the best matching reason code please.</desc>
       </param>
-      <param name="progress" type="IProgress" dir="return">
+      <param name="progress" type="IProgress" dir="in">
         <desc>Progress object to track the operation completion.</desc>
       </param>
+      <param name="stateFilePath" type="wstring" dir="in">
+        <desc>File path the VM process must save the execution state to.</desc>
+      </param>
+      <param name="pauseVM" type="boolean" dir="in">
+        <desc>The VM should be paused before saving state. It is automatically
+        unpaused on error in the "vanilla save state" case.</desc>
+      </param>
+      <param name="leftPaused" type="boolean" dir="return">
+        <desc>Returns if the VM was left in paused state, which is necessary
+        in many situations (snapshots, teleportation).</desc>
+      </param>
+    </method>
+
+    <method name="cancelSaveStateWithReason">
+      <desc>
+        Internal method for cancelling a VM save state.
+        <see><link to="IInternalSessionControl::saveStateWithReason"/></see>
+      </desc>
     </method>
 
   </interface>
@@ -20194,7 +20115,7 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
   -->
   <enum
     name="VBoxEventType"
-    uuid="1622f8d2-6c76-4410-9e78-86e083046efc"
+    uuid="b2ddb312-2f9e-4e69-98df-7235e43b2149"
     >
 
     <desc>
@@ -20573,9 +20494,13 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
         See <link to="IHostNameResolutionConfigurationChangeEvent">IHostNameResolutionConfigurationChangeEvent</link>.
       </desc>
     </const>
-    <!-- OnHostNameResolutionConfigurationChange -->
+    <const name="OnSnapshotRestored" value="95">
+      <desc>
+        See <link to="ISnapshotRestoredEvent">ISnapshotRestoredEvent</link>.
+      </desc>
+    </const>
     <!-- Last event marker -->
-    <const name="Last" value="95">
+    <const name="Last" value="96">
       <desc>
         Must be last event, used for iterations and structures relying on numerical event values.
       </desc>
@@ -21076,6 +21001,18 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
   </interface>
 
   <interface
+    name="ISnapshotRestoredEvent" extends="ISnapshotEvent"
+    uuid="f4d803b4-9b2d-4377-bfe6-9702e881516b"
+    wsmap="managed" autogen="VBoxEvent" id="OnSnapshotRestored"
+    >
+    <desc>
+      Snapshot of the given machine has been restored.
+      <see><link to="ISnapshot"/></see>
+    </desc>
+    <attribute name="midlDoesNotLikEmptyInterfaces" readonly="yes" type="boolean"/>
+  </interface>
+
+  <interface
     name="ISnapshotChangedEvent" extends="ISnapshotEvent"
     uuid="07541941-8079-447a-a33e-47a69c7980db"
     wsmap="managed" autogen="VBoxEvent" id="OnSnapshotChanged"
@@ -21973,7 +21910,7 @@ Snapshot 1 (B.vdi)            Snapshot 1 (B.vdi)
       to @c true. In case of fatal errors, the virtual machine
       execution is always paused before calling this notification, and
       the notification handler is supposed either to immediately save
-      the virtual machine state using <link to="IConsole::saveState"/>
+      the virtual machine state using <link to="IMachine::saveState"/>
       or power it off using <link to="IConsole::powerDown"/>.
       Resuming the execution can lead to unpredictable results.
 
diff --git a/src/VBox/Main/include/ApplianceImpl.h b/src/VBox/Main/include/ApplianceImpl.h
index f9ecb03..71303cf 100644
--- a/src/VBox/Main/include/ApplianceImpl.h
+++ b/src/VBox/Main/include/ApplianceImpl.h
@@ -104,6 +104,9 @@ private:
                   const com::Utf8Str &aPath,
                   ComPtr<IProgress> &aProgress);
     HRESULT getWarnings(std::vector<com::Utf8Str> &aWarnings);
+    HRESULT getPasswordIds(std::vector<com::Utf8Str> &aIdentifiers);
+    HRESULT addPasswords(const std::vector<com::Utf8Str> &aIdentifiers,
+                         const std::vector<com::Utf8Str> &aPasswords);
 
     /** weak VirtualBox parent */
     VirtualBox* const mVirtualBox;
diff --git a/src/VBox/Main/include/ApplianceImplPrivate.h b/src/VBox/Main/include/ApplianceImplPrivate.h
index 6502563..e02aa58 100644
--- a/src/VBox/Main/include/ApplianceImplPrivate.h
+++ b/src/VBox/Main/include/ApplianceImplPrivate.h
@@ -20,7 +20,9 @@
 class VirtualSystemDescription;
 
 #include "ovfreader.h"
+#include "SecretKeyStore.h"
 #include <map>
+#include <vector>
 #include <iprt/vfs.h>
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -60,6 +62,7 @@ struct Appliance::Data
       , ulWeightForManifestOperation(0)
       , ulTotalDisksMB(0)
       , cDisks(0)
+      , m_cPwProvided(0)
     {
     }
 
@@ -98,6 +101,13 @@ struct Appliance::Data
     ULONG               cDisks;
 
     std::list<Guid>     llGuidsMachinesCreated;
+
+    /** Sequence of password identifiers to encrypt disk images during export. */
+    std::vector<com::Utf8Str> m_vecPasswordIdentifiers;
+    /** Secret key store used to hold the passwords during export. */
+    SecretKeyStore            *m_pSecretKeyStore;
+    /** Number of passwords provided. */
+    uint32_t                  m_cPwProvided;
 };
 
 struct Appliance::XMLStack
diff --git a/src/VBox/Main/include/ConsoleImpl.h b/src/VBox/Main/include/ConsoleImpl.h
index 76ec4ca..5209452 100644
--- a/src/VBox/Main/include/ConsoleImpl.h
+++ b/src/VBox/Main/include/ConsoleImpl.h
@@ -21,6 +21,7 @@
 #include "VirtualBoxBase.h"
 #include "VBox/com/array.h"
 #include "EventImpl.h"
+#include "SecretKeyStore.h"
 #include "ConsoleWrap.h"
 
 class Guest;
@@ -153,6 +154,7 @@ public:
     ConsoleVRDPServer *i_consoleVRDPServer() const { return mConsoleVRDPServer; }
 
     HRESULT i_updateMachineState(MachineState_T aMachineState);
+    HRESULT i_getNominalState(MachineState_T &aNominalState);
 
     // events from IInternalSessionControl
     HRESULT i_onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL changeAdapter);
@@ -186,6 +188,7 @@ public:
     HRESULT i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
                                 ULONG aSourceIdx, ULONG aTargetIdx,
                                 IProgress *aProgress);
+    HRESULT i_reconfigureMediumAttachments(const std::vector<ComPtr<IMediumAttachment> > &aAttachments);
     int i_hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName);
     VMMDev *i_getVMMDev() { return m_pVMMDev; }
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
@@ -228,8 +231,9 @@ public:
     void i_enableVMMStatistics(BOOL aEnable);
 
     HRESULT i_pause(Reason_T aReason);
-    HRESULT i_resume(Reason_T aReason);
-    HRESULT i_saveState(Reason_T aReason, IProgress **aProgress);
+    HRESULT i_resume(Reason_T aReason, AutoWriteLock &alock);
+    HRESULT i_saveState(Reason_T aReason, const ComPtr<IProgress> &aProgress, const Utf8Str &aStateFilePath, bool fPauseVM, bool &fLeftPaused);
+    HRESULT i_cancelSaveState();
 
     // callback callers (partly; for some events console callbacks are notified
     // directly from IInternalSessionControl event handlers declared above)
@@ -316,9 +320,6 @@ private:
     HRESULT sleepButton();
     HRESULT getPowerButtonHandled(BOOL *aHandled);
     HRESULT getGuestEnteredACPIMode(BOOL *aEntered);
-    HRESULT saveState(ComPtr<IProgress> &aProgress);
-    HRESULT adoptSavedState(const com::Utf8Str &aSavedStateFile);
-    HRESULT discardSavedState(BOOL aFRemoveFile);
     HRESULT getDeviceActivity(const std::vector<DeviceType_T> &aType,
                               std::vector<DeviceActivity_T> &aActivity);
     HRESULT attachUSBDevice(const com::Guid &aId, const com::Utf8Str &aCaptureFilename);
@@ -333,18 +334,6 @@ private:
                                BOOL aWritable,
                                BOOL aAutomount);
     HRESULT removeSharedFolder(const com::Utf8Str &aName);
-    HRESULT takeSnapshot(const com::Utf8Str &aName,
-                         const com::Utf8Str &aDescription,
-                         ComPtr<IProgress> &aProgress);
-    HRESULT deleteSnapshot(const com::Guid &aId,
-                           ComPtr<IProgress> &aProgress);
-    HRESULT deleteSnapshotAndAllChildren(const com::Guid &aId,
-                                         ComPtr<IProgress> &aProgress);
-    HRESULT deleteSnapshotRange(const com::Guid &aStartId,
-                                const com::Guid &aEndId,
-                                ComPtr<IProgress> &aProgress);
-    HRESULT restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot,
-                            ComPtr<IProgress> &aProgress);
     HRESULT teleport(const com::Utf8Str &aHostname,
                      ULONG aTcpport,
                      const com::Utf8Str &aPassword,
@@ -581,50 +570,10 @@ public:
         LONG     iPort;
     };
 
-    /**
-     * Class for managing cryptographic keys.
-     * @todo: Replace with a keystore implementation once it is ready.
-     */
-    class SecretKey
-    {
-        public:
-            SecretKey() { }
-
-            SecretKey(uint8_t *pbKey, size_t cbKey, bool fRemoveOnSuspend)
-               : m_cRefs(0),
-                 m_pbKey(pbKey),
-                 m_cbKey(cbKey),
-                 m_fRemoveOnSuspend(fRemoveOnSuspend),
-                 m_cDisks(0)
-            { }
-
-            ~SecretKey()
-            {
-                RTMemSaferFree(m_pbKey, m_cbKey);
-                m_cRefs = 0;
-                m_pbKey = NULL;
-                m_cbKey = 0;
-                m_fRemoveOnSuspend = false;
-                m_cDisks = 0;
-            }
-
-            /** Reference counter of the key. */
-            volatile uint32_t m_cRefs;
-            /** Key material. */
-            uint8_t          *m_pbKey;
-            /** Size of the key in bytes. */
-            size_t            m_cbKey;
-            /** Flag whether to remove the key on suspend. */
-            bool              m_fRemoveOnSuspend;
-            /** Number of disks using this key. */
-            uint32_t          m_cDisks;
-    };
-
     typedef std::map<Utf8Str, ComObjPtr<SharedFolder> > SharedFolderMap;
     typedef std::map<Utf8Str, SharedFolderData> SharedFolderDataMap;
     typedef std::map<Utf8Str, ComPtr<IMediumAttachment> > MediumAttachmentMap;
     typedef std::list <USBStorageDevice> USBStorageDeviceList;
-    typedef std::map<Utf8Str, SecretKey *> SecretKeyMap;
 
 private:
 
@@ -789,8 +738,6 @@ private:
     HRESULT i_doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PUVM pUVM, bool fSilent);
     HRESULT i_doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PUVM pUVM, bool fSilent);
 
-    static DECLCALLBACK(int)    i_fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser);
-
     static DECLCALLBACK(int)    i_stateProgressCallback(PUVM pUVM, unsigned uPercent, void *pvUser);
 
     static DECLCALLBACK(void)   i_genericVMSetErrorCallback(PUVM pUVM, void *pvUser, int rc, RT_SRC_POS_DECL,
@@ -804,7 +751,6 @@ private:
     void                        i_detachAllUSBDevices(bool aDone);
 
     static DECLCALLBACK(int)    i_powerUpThread(RTTHREAD Thread, void *pvUser);
-    static DECLCALLBACK(int)    i_saveStateThread(RTTHREAD Thread, void *pvUser);
     static DECLCALLBACK(int)    i_powerDownThread(RTTHREAD Thread, void *pvUser);
 
     static DECLCALLBACK(int)    i_vmm2User_SaveState(PCVMM2USERMETHODS pThis, PUVM pUVM);
@@ -996,12 +942,12 @@ private:
     /** List of attached USB storage devices. */
     USBStorageDeviceList mUSBStorageDevices;
 
-    /** Map of secret keys used for disk encryption. */
-    SecretKeyMap         m_mapSecretKeys;
+    /** Store for secret keys. */
+    SecretKeyStore * const m_pKeyStore;
     /** Number of disks configured for encryption. */
-    unsigned             m_cDisksEncrypted;
+    unsigned               m_cDisksEncrypted;
     /** Number of disks which have the key in the map. */
-    unsigned             m_cDisksPwProvided;
+    unsigned               m_cDisksPwProvided;
 
     /** Pointer to the key consumer -> provider (that's us) callbacks. */
     struct MYPDMISECKEY : public PDMISECKEY
@@ -1035,7 +981,7 @@ private:
      * Console::PowerDown, which automatically cancels out the running snapshot /
      * teleportation operation, will cancel the teleportation / live snapshot
      * operation before starting. */
-    ComObjPtr<Progress> mptrCancelableProgress;
+    ComPtr<IProgress> mptrCancelableProgress;
 
     ComPtr<IEventListener> mVmListener;
 
diff --git a/src/VBox/Main/include/DisplayImpl.h b/src/VBox/Main/include/DisplayImpl.h
index 5cf517b..ca3d50f 100644
--- a/src/VBox/Main/include/DisplayImpl.h
+++ b/src/VBox/Main/include/DisplayImpl.h
@@ -47,6 +47,7 @@ typedef struct _DISPLAYFBINFO
     uint32_t u32InformationSize;
 
     ComPtr<IFramebuffer> pFramebuffer;
+    com::Guid framebufferId;
     ComPtr<IDisplaySourceBitmap> pSourceBitmap;
     bool fDisabled;
 
@@ -224,8 +225,10 @@ private:
                                         LONG *aYOrigin,
                                         GuestMonitorStatus_T *aGuestMonitorStatus);
     virtual HRESULT attachFramebuffer(ULONG aScreenId,
-                                      const ComPtr<IFramebuffer> &aFramebuffer);
-    virtual HRESULT detachFramebuffer(ULONG aScreenId);
+                                      const ComPtr<IFramebuffer> &aFramebuffer,
+                                      com::Guid &aId);
+    virtual HRESULT detachFramebuffer(ULONG aScreenId,
+                                      const com::Guid &aId);
     virtual HRESULT queryFramebuffer(ULONG aScreenId,
                                      ComPtr<IFramebuffer> &aFramebuffer);
     virtual HRESULT setVideoModeHint(ULONG aDisplay,
diff --git a/src/VBox/Main/include/Global.h b/src/VBox/Main/include/Global.h
index 551d8cf..2ee1a14 100644
--- a/src/VBox/Main/include/Global.h
+++ b/src/VBox/Main/include/Global.h
@@ -96,34 +96,11 @@ public:
      * recommended way to detect if the VM is online (being executed in a
      * dedicated process) or not. Note that some online states are also
      * transitional states (see #IsTransitional()).
-     *
-     * @remarks Saving may actually be an offline state according to the
-     *          documentation (offline snapshot).
      */
     static bool IsOnline(MachineState_T aState)
     {
-#if 0
         return aState >= MachineState_FirstOnline &&
                aState <= MachineState_LastOnline;
-#else
-        switch (aState)
-        {
-            case MachineState_Running:
-            case MachineState_Paused:
-            case MachineState_Teleporting:
-            case MachineState_LiveSnapshotting:
-            case MachineState_Stuck:
-            case MachineState_Starting:
-            case MachineState_Stopping:
-            case MachineState_Saving:
-            case MachineState_Restoring:
-            case MachineState_TeleportingPausedVM:
-            case MachineState_TeleportingIn:
-                return true;
-            default:
-                return false;
-        }
-#endif
     }
 
     /**
@@ -135,28 +112,8 @@ public:
      */
     static bool IsTransient(MachineState_T aState)
     {
-#if 0
         return aState >= MachineState_FirstTransient &&
                aState <= MachineState_LastTransient;
-#else
-        switch (aState)
-        {
-            case MachineState_Teleporting:
-            case MachineState_LiveSnapshotting:
-            case MachineState_Starting:
-            case MachineState_Stopping:
-            case MachineState_Saving:
-            case MachineState_Restoring:
-            case MachineState_TeleportingPausedVM:
-            case MachineState_TeleportingIn:
-            case MachineState_RestoringSnapshot:
-            case MachineState_DeletingSnapshot:
-            case MachineState_SettingUp:
-                return true;
-            default:
-                return false;
-        }
-#endif
     }
 
     /**
diff --git a/src/VBox/Main/include/MachineImpl.h b/src/VBox/Main/include/MachineImpl.h
index e62ecb6..d5e423a 100644
--- a/src/VBox/Main/include/MachineImpl.h
+++ b/src/VBox/Main/include/MachineImpl.h
@@ -124,6 +124,9 @@ public:
          */
         struct Session
         {
+            /** Type of lock which created this session */
+            LockType_T mLockType;
+
             /** Control of the direct session opened by lockMachine() */
             ComPtr<IInternalSessionControl> mDirectControl;
 
@@ -146,7 +149,7 @@ public:
             SessionState_T mState;
 
             /** Session type string (for indirect sessions) */
-            Bstr mType;
+            Utf8Str mType;
 
             /** Session machine object */
             ComObjPtr<SessionMachine> mMachine;
@@ -596,7 +599,7 @@ public:
                                                             fSetError);
     }
 
-
+    static HRESULT i_setErrorStatic(HRESULT aResultCode, const char *pcszMsg, ...);
 
 protected:
 
@@ -711,9 +714,6 @@ protected:
     void i_copyFrom(Machine *aThat);
     bool i_isControllerHotplugCapable(StorageControllerType_T enmCtrlType);
 
-    struct DeleteTask;
-    static DECLCALLBACK(int) deleteThread(RTTHREAD Thread, void *pvUser);
-    HRESULT i_deleteTaskWorker(DeleteTask &task);
     Utf8Str i_getExtraData(const Utf8Str &strKey);
 
 #ifdef VBOX_WITH_GUEST_PROPS
@@ -778,6 +778,60 @@ protected:
 
     uint64_t                        uRegistryNeedsSaving;
 
+    /**
+     * Abstract base class for all Machine or SessionMachine related
+     * asynchronous tasks. This is necessary since RTThreadCreate cannot call
+     * a (non-static) method as its thread function, so instead we have it call
+     * the static Machine::taskHandler, which then calls the handler() method
+     * in here (implemented by the subclasses).
+     */
+    struct Task
+    {
+        Task(Machine *m, Progress *p, const Utf8Str &t)
+            : m_pMachine(m),
+              m_machineCaller(m),
+              m_pProgress(p),
+              m_strTaskName(t),
+              m_machineStateBackup(m->mData->mMachineState) // save the current machine state
+        {}
+
+        HRESULT createThread()
+        {
+            int vrc = RTThreadCreate(NULL,
+                                     taskHandler,
+                                     (void *)this,
+                                     0,
+                                     RTTHREADTYPE_MAIN_WORKER,
+                                     0,
+                                     m_strTaskName.c_str());
+            if (RT_FAILURE(vrc))
+            {
+                HRESULT rc = Machine::i_setErrorStatic(E_FAIL, Machine::tr("Could not create thread \"%s\" (%Rrc)"), m_strTaskName.c_str(), vrc);
+                delete this;
+                return rc;
+            }
+            return S_OK;
+        }
+
+        void modifyBackedUpState(MachineState_T s)
+        {
+            *const_cast<MachineState_T *>(&m_machineStateBackup) = s;
+        }
+
+        virtual void handler() = 0;
+
+        ComObjPtr<Machine>       m_pMachine;
+        AutoCaller                      m_machineCaller;
+        ComObjPtr<Progress>             m_pProgress;
+        Utf8Str                         m_strTaskName;
+        const MachineState_T            m_machineStateBackup;
+    };
+
+    struct DeleteConfigTask;
+    void i_deleteConfigHandler(DeleteConfigTask &task);
+
+    static DECLCALLBACK(int) taskHandler(RTTHREAD thread, void *pvUser);
+
     friend class SessionMachine;
     friend class SnapshotMachine;
     friend class Appliance;
@@ -1130,11 +1184,26 @@ private:
                     CloneMode_T aMode,
                     const std::vector<CloneOptions_T> &aOptions,
                     ComPtr<IProgress> &aProgress);
+    HRESULT saveState(ComPtr<IProgress> &aProgress);
+    HRESULT adoptSavedState(const com::Utf8Str &aSavedStateFile);
+    HRESULT discardSavedState(BOOL aFRemoveFile);
+    HRESULT takeSnapshot(const com::Utf8Str &aName,
+                         const com::Utf8Str &aDescription,
+                         BOOL aPause,
+                         ComPtr<IProgress> &aProgress);
+    HRESULT deleteSnapshot(const com::Guid &aId,
+                           ComPtr<IProgress> &aProgress);
+    HRESULT deleteSnapshotAndAllChildren(const com::Guid &aId,
+                                         ComPtr<IProgress> &aProgress);
+    HRESULT deleteSnapshotRange(const com::Guid &aStartId,
+                                const com::Guid &aEndId,
+                                ComPtr<IProgress> &aProgress);
+    HRESULT restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot,
+                            ComPtr<IProgress> &aProgress);
 
     // wrapped IInternalMachineControl properties
 
     // wrapped IInternalMachineControl methods
-    HRESULT setRemoveSavedStateFile(BOOL aRemove);
     HRESULT updateState(MachineState_T aState);
     HRESULT beginPowerUp(const ComPtr<IProgress> &aProgress);
     HRESULT endPowerUp(LONG aResult);
@@ -1144,36 +1213,15 @@ private:
     HRESULT runUSBDeviceFilters(const ComPtr<IUSBDevice> &aDevice,
                                 BOOL *aMatched,
                                 ULONG *aMaskedInterfaces);
-    HRESULT captureUSBDevice(const com::Guid &aId, const com::Utf8Str &aCaptureFilename);
+    HRESULT captureUSBDevice(const com::Guid &aId,
+                             const com::Utf8Str &aCaptureFilename);
     HRESULT detachUSBDevice(const com::Guid &aId,
                             BOOL aDone);
     HRESULT autoCaptureUSBDevices();
     HRESULT detachAllUSBDevices(BOOL aDone);
     HRESULT onSessionEnd(const ComPtr<ISession> &aSession,
                          ComPtr<IProgress> &aProgress);
-    HRESULT beginSavingState(ComPtr<IProgress> &aProgress,
-                             com::Utf8Str &aStateFilePath);
-    HRESULT endSavingState(LONG aResult,
-                           const com::Utf8Str &aErrMsg);
-    HRESULT adoptSavedState(const com::Utf8Str &aSavedStateFile);
-    HRESULT beginTakingSnapshot(const ComPtr<IConsole> &aInitiator,
-                                const com::Utf8Str &aName,
-                                const com::Utf8Str &aDescription,
-                                const ComPtr<IProgress> &aConsoleProgress,
-                                BOOL aFTakingSnapshotOnline,
-                                com::Utf8Str &aStateFilePath);
-    HRESULT endTakingSnapshot(BOOL aSuccess);
-    HRESULT deleteSnapshot(const ComPtr<IConsole> &aInitiator,
-                           const com::Guid &aStartId,
-                           const com::Guid &aEndId,
-                           BOOL aDeleteAllChildren,
-                           MachineState_T *aMachineState,
-                           ComPtr<IProgress> &aProgress);
     HRESULT finishOnlineMergeMedium();
-    HRESULT restoreSnapshot(const ComPtr<IConsole> &aInitiator,
-                            const ComPtr<ISnapshot> &aSnapshot,
-                            MachineState_T *aMachineState,
-                            ComPtr<IProgress> &aProgress);
     HRESULT pullGuestProperties(std::vector<com::Utf8Str> &aNames,
                                 std::vector<com::Utf8Str> &aValues,
                                 std::vector<LONG64> &aTimestamps,
@@ -1202,10 +1250,6 @@ private:
                                ULONG aMemSharedTotal,
                                ULONG aVmNetRx,
                                ULONG aVmNetTx);
-
-
-
-
 };
 
 // SessionMachine class
@@ -1301,6 +1345,8 @@ public:
     HRESULT i_lockMedia();
     HRESULT i_unlockMedia();
 
+    HRESULT i_saveStateWithReason(Reason_T aReason, ComPtr<IProgress> &aProgress);
+
 private:
 
     // wrapped IInternalMachineControl properties
@@ -1323,29 +1369,7 @@ private:
     HRESULT detachAllUSBDevices(BOOL aDone);
     HRESULT onSessionEnd(const ComPtr<ISession> &aSession,
                          ComPtr<IProgress> &aProgress);
-    HRESULT beginSavingState(ComPtr<IProgress> &aProgress,
-                             com::Utf8Str &aStateFilePath);
-    HRESULT endSavingState(LONG aResult,
-                           const com::Utf8Str &aErrMsg);
-    HRESULT adoptSavedState(const com::Utf8Str &aSavedStateFile);
-    HRESULT beginTakingSnapshot(const ComPtr<IConsole> &aInitiator,
-                                const com::Utf8Str &aName,
-                                const com::Utf8Str &aDescription,
-                                const ComPtr<IProgress> &aConsoleProgress,
-                                BOOL aFTakingSnapshotOnline,
-                                com::Utf8Str &aStateFilePath);
-    HRESULT endTakingSnapshot(BOOL aSuccess);
-    HRESULT deleteSnapshot(const ComPtr<IConsole> &aInitiator,
-                           const com::Guid &aStartId,
-                           const com::Guid &aEndId,
-                           BOOL aDeleteAllChildren,
-                           MachineState_T *aMachineState,
-                           ComPtr<IProgress> &aProgress);
     HRESULT finishOnlineMergeMedium();
-    HRESULT restoreSnapshot(const ComPtr<IConsole> &aInitiator,
-                            const ComPtr<ISnapshot> &aSnapshot,
-                            MachineState_T *aMachineState,
-                            ComPtr<IProgress> &aProgress);
     HRESULT pullGuestProperties(std::vector<com::Utf8Str> &aNames,
                                 std::vector<com::Utf8Str> &aValues,
                                 std::vector<LONG64> &aTimestamps,
@@ -1379,32 +1403,57 @@ private:
     struct ConsoleTaskData
     {
         ConsoleTaskData()
-            : mLastState(MachineState_Null), mDeleteSnapshotInfo(NULL)
+            : mLastState(MachineState_Null),
+              mDeleteSnapshotInfo(NULL)
         { }
 
         MachineState_T mLastState;
         ComObjPtr<Progress> mProgress;
 
-        // used when taking snapshot
-        ComObjPtr<Snapshot> mSnapshot;
-
-        // used when deleting online snapshot
+        // used when deleting online snaphshot
         void *mDeleteSnapshotInfo;
-
-        // used when saving state (either as part of a snapshot or separate)
-        Utf8Str strStateFilePath;
     };
 
+    struct SaveStateTask;
     struct SnapshotTask;
+    struct TakeSnapshotTask;
     struct DeleteSnapshotTask;
     struct RestoreSnapshotTask;
 
+    friend struct TakeSnapshotTask;
     friend struct DeleteSnapshotTask;
     friend struct RestoreSnapshotTask;
 
-    HRESULT i_endSavingState(HRESULT aRC, const Utf8Str &aErrMsg);
+    void i_saveStateHandler(SaveStateTask &aTask);
+
+    // Override some functionality for SessionMachine, this is where the
+    // real action happens (the Machine methods are just dummies).
+    HRESULT saveState(ComPtr<IProgress> &aProgress);
+    HRESULT adoptSavedState(const com::Utf8Str &aSavedStateFile);
+    HRESULT discardSavedState(BOOL aFRemoveFile);
+    HRESULT takeSnapshot(const com::Utf8Str &aName,
+                         const com::Utf8Str &aDescription,
+                         BOOL aPause,
+                         ComPtr<IProgress> &aProgress);
+    HRESULT deleteSnapshot(const com::Guid &aId,
+                           ComPtr<IProgress> &aProgress);
+    HRESULT deleteSnapshotAndAllChildren(const com::Guid &aId,
+                                         ComPtr<IProgress> &aProgress);
+    HRESULT deleteSnapshotRange(const com::Guid &aStartId,
+                                const com::Guid &aEndId,
+                                ComPtr<IProgress> &aProgress);
+    HRESULT restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot,
+                            ComPtr<IProgress> &aProgress);
+
     void i_releaseSavedStateFile(const Utf8Str &strSavedStateFile, Snapshot *pSnapshotToIgnore);
 
+    void i_takeSnapshotHandler(TakeSnapshotTask &aTask);
+    static void i_takeSnapshotProgressCancelCallback(void *pvUser);
+    HRESULT i_finishTakingSnapshot(TakeSnapshotTask &aTask, AutoWriteLock &alock, bool aSuccess);
+    HRESULT i_deleteSnapshot(const com::Guid &aStartId,
+                             const com::Guid &aEndId,
+                             BOOL aDeleteAllChildren,
+                             ComPtr<IProgress> &aProgress);
     void i_deleteSnapshotHandler(DeleteSnapshotTask &aTask);
     void i_restoreSnapshotHandler(RestoreSnapshotTask &aTask);
 
@@ -1450,8 +1499,6 @@ private:
     ClientToken *mClientToken;
 
     int miNATNetworksStarted;
-
-    static DECLCALLBACK(int) taskHandler(RTTHREAD thread, void *pvUser);
 };
 
 // SnapshotMachine class
diff --git a/src/VBox/Main/include/MediumImpl.h b/src/VBox/Main/include/MediumImpl.h
index d12cba4..61aaba9 100644
--- a/src/VBox/Main/include/MediumImpl.h
+++ b/src/VBox/Main/include/MediumImpl.h
@@ -23,6 +23,7 @@
 #include "MediumWrap.h"
 #include "VirtualBoxBase.h"
 #include "AutoCaller.h"
+#include "SecretKeyStore.h"
 class Progress;
 class MediumFormat;
 class MediumLockList;
@@ -203,6 +204,7 @@ public:
     HRESULT i_exportFile(const char *aFilename,
                          const ComObjPtr<MediumFormat> &aFormat,
                          MediumVariant_T aVariant,
+                         SecretKeyStore *pKeyStore,
                          PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser,
                          const ComObjPtr<Progress> &aProgress);
     HRESULT i_importFile(const char *aFilename,
@@ -216,6 +218,8 @@ public:
                         const ComObjPtr<Medium> &aParent, IProgress **aProgress,
                         uint32_t idxSrcImageSame, uint32_t idxDstImageSame);
 
+    const Utf8Str& i_getKeyId();
+
 private:
 
     // wrapped IMedium properties
diff --git a/src/VBox/Main/include/SecretKeyStore.h b/src/VBox/Main/include/SecretKeyStore.h
new file mode 100644
index 0000000..c10dd00
--- /dev/null
+++ b/src/VBox/Main/include/SecretKeyStore.h
@@ -0,0 +1,189 @@
+/** @file
+ * Main - Secret key interface.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ____H_SECRETKEYSTORE
+#define ____H_SECRETKEYSTORE
+
+#include "VirtualBoxBase.h"
+#include "VBox/com/array.h"
+
+class SecretKey
+{
+    public:
+
+        /**
+         * Constructor for a secret key.
+         *
+         * @param pbKey                 The key buffer.
+         * @param cbKey                 Size of the key.
+         * @param fKeyBufNonPageable    Flag whether the key buffer should be non pageable.
+         */
+        SecretKey(const uint8_t *pbKey, size_t cbKey, bool fKeyBufNonPageable);
+
+        /**
+         * Secret key destructor.
+         */
+        ~SecretKey();
+
+        /**
+         * Increments the reference counter of the key.
+         *
+         * @returns The new reference count.
+         */
+        uint32_t retain();
+
+        /**
+         * Releases a reference of the key.
+         * If the reference counter reaches 0 the key buffer might be protected
+         * against further access or the data will become scrambled.
+         *
+         * @returns The new reference count.
+         */
+        uint32_t release();
+
+        /**
+         * Returns the reference count of the secret key.
+         */
+        uint32_t refCount();
+
+        /**
+         * Sets the possible number of users for this key.
+         *
+         * @returns VBox status code.
+         * @param   cUsers              The possible number of user for this key.
+         */
+        int setUsers(uint32_t cUsers);
+
+        /**
+         * Returns the possible amount of users.
+         *
+         * @returns Possible amount of users.
+         */
+        uint32_t getUsers();
+
+        /**
+         * Sets the remove on suspend flag.
+         *
+         * @returns VBox status code.
+         * @param   fRemoveOnSuspend    Flag whether to remove the key on host suspend.
+         */
+        int setRemoveOnSuspend(bool fRemoveOnSuspend);
+
+        /**
+         * Returns whether the key should be destroyed on suspend.
+         */
+        bool getRemoveOnSuspend();
+
+        /**
+         * Returns the buffer to the key.
+         */
+        const void *getKeyBuffer();
+
+        /**
+         * Returns the size of the key.
+         */
+        size_t getKeySize();
+
+    private:
+        /** Reference counter of the key. */
+        volatile uint32_t m_cRefs;
+        /** Key material. */
+        uint8_t          *m_pbKey;
+        /** Size of the key in bytes. */
+        size_t            m_cbKey;
+        /** Flag whether to remove the key on suspend. */
+        bool              m_fRemoveOnSuspend;
+        /** Number of entities which will use this key. */
+        uint32_t          m_cUsers;
+};
+
+class SecretKeyStore
+{
+    public:
+
+        /**
+         * Constructor for a secret key store.
+         *
+         * @param fKeyBufNonPageable    Flag whether the key buffer is required to
+         *                              be non pageable.
+         */
+        SecretKeyStore(bool fKeyBufNonPageable);
+
+        /**
+         * Destructor of a secret key store. This will free all stored secret keys
+         * inluding the key buffers. Make sure there no one accesses one of the keys
+         * stored.
+         */
+        ~SecretKeyStore();
+
+        /**
+         * Add a secret key to the store.
+         *
+         * @returns VBox status code.
+         * @param   strKeyId            The key identifier.
+         * @param   pbKey               The key to store.
+         * @param   cbKey               Size of the key.
+         */
+        int addSecretKey(const com::Utf8Str &strKeyId, const uint8_t *pbKey, size_t cbKey);
+
+        /**
+         * Deletes a key from the key store associated with the given identifier.
+         *
+         * @returns VBox status code.
+         * @param   strKeyId            The key identifier.
+         */
+        int deleteSecretKey(const com::Utf8Str &strKeyId);
+
+        /**
+         * Returns the secret key object associated with the given identifier.
+         * This increments the reference counter of the secret key object.
+         *
+         * @returns VBox status code.
+         * @param   strKeyId            The key identifier.
+         * @param   ppKey               Where to store the secret key object on success.
+         */
+        int retainSecretKey(const com::Utf8Str &strKeyId, SecretKey **ppKey);
+
+        /**
+         * Releases a reference to the secret key object.
+         *
+         * @returns VBox status code.
+         * @param   strKeyId            The key identifier.
+         */
+        int releaseSecretKey(const com::Utf8Str &strKeyId);
+
+        /**
+         * Deletes all secret keys from the key store.
+         *
+         * @returns VBox status code.
+         * @param   fSuspend           Flag whether to delete only keys which are
+         *                             marked for deletion during a suspend.
+         * @param   fForce             Flag whether to force deletion if some keys
+         *                             are still in use. Otherwise an error is returned.
+         */
+        int deleteAllSecretKeys(bool fSuspend, bool fForce);
+
+    private:
+
+        typedef std::map<com::Utf8Str, SecretKey *> SecretKeyMap;
+
+        /** The map to map key identifers to secret keys. */
+        SecretKeyMap m_mapSecretKeys;
+        /** Flag whether key buffers should be non pagable. */
+        bool         m_fKeyBufNonPageable;
+};
+
+#endif  /* !____H_SECRETKEYSTORE */
diff --git a/src/VBox/Main/include/SessionImpl.h b/src/VBox/Main/include/SessionImpl.h
index f2ec1df..1298065 100644
--- a/src/VBox/Main/include/SessionImpl.h
+++ b/src/VBox/Main/include/SessionImpl.h
@@ -52,16 +52,21 @@ public:
 
 private:
 
-    // Wrapped Isession properties
+    // Wrapped ISession properties
     HRESULT getState(SessionState_T *aState);
     HRESULT getType(SessionType_T *aType);
     HRESULT getMachine(ComPtr<IMachine> &aMachine);
     HRESULT getConsole(ComPtr<IConsole> &aConsole);
 
-    // Wrapped Isession methods
+    // Wrapped ISession methods
     HRESULT unlockMachine();
+
+    // Wrapped IInternalSessionControl properties
     HRESULT getPID(ULONG *aPid);
-    HRESULT getRemoteConsole(ComPtr<IConsole> &aConsole);
+    HRESULT getRemoteConsole(ComPtr<IConsole> &aRemoteConsole);
+    HRESULT getNominalState(MachineState_T *aNominalState);
+
+    // Wrapped IInternalSessionControl methods
 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
     HRESULT assignMachine(const ComPtr<IMachine> &aMachine,
                           LockType_T aLockType,
@@ -120,12 +125,19 @@ private:
                               ULONG aSourceIdx,
                               ULONG aTargetIdx,
                               const ComPtr<IProgress> &aProgress);
+    HRESULT reconfigureMediumAttachments(const std::vector<ComPtr<IMediumAttachment> > &aAttachments);
     HRESULT enableVMMStatistics(BOOL aEnable);
     HRESULT pauseWithReason(Reason_T aReason);
     HRESULT resumeWithReason(Reason_T aReason);
     HRESULT saveStateWithReason(Reason_T aReason,
-                                ComPtr<IProgress> &aProgress);
-    HRESULT unlockMachine(bool aFinalRelease, bool aFromServer);
+                                const ComPtr<IProgress> &aProgress,
+                                const Utf8Str &aStateFilePath,
+                                BOOL aPauseVM,
+                                BOOL *aLeftPaused);
+    HRESULT cancelSaveStateWithReason();
+
+
+    HRESULT i_unlockMachine(bool aFinalRelease, bool aFromServer);
 
     SessionState_T mState;
     SessionType_T mType;
diff --git a/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h b/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h
index 8f02cf9..d7e1d02 100644
--- a/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h
+++ b/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -38,8 +38,29 @@ public:
         COM_INTERFACE_ENTRY(IErrorInfo)
         COM_INTERFACE_ENTRY(IVirtualBoxErrorInfo)
         COM_INTERFACE_ENTRY(IDispatch)
+        COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler)
     END_COM_MAP()
 
+    HRESULT FinalConstruct()
+    {
+#ifndef VBOX_WITH_XPCOM
+        return CoCreateFreeThreadedMarshaler((IUnknown *)(void *)this, &m_pUnkMarshaler);
+#else
+        return S_OK;
+#endif
+    }
+
+    void FinalRelease()
+    {
+#ifndef VBOX_WITH_XPCOM
+        if (m_pUnkMarshaler)
+        {
+            m_pUnkMarshaler->Release();
+            m_pUnkMarshaler = NULL;
+        }
+#endif
+    }
+
 #ifndef VBOX_WITH_XPCOM
 
     HRESULT init(IErrorInfo *aInfo);
@@ -127,6 +148,10 @@ private:
     Guid    m_IID;
     Utf8Str m_strComponent;
     ComPtr<IVirtualBoxErrorInfo> mNext;
+
+#ifndef VBOX_WITH_XPCOM
+    IUnknown *m_pUnkMarshaler;
+#endif
 };
 
 #endif // !____H_VIRTUALBOXERRORINFOIMPL
diff --git a/src/VBox/Main/include/VirtualBoxImpl.h b/src/VBox/Main/include/VirtualBoxImpl.h
index 4bf33c2..0a6daea 100644
--- a/src/VBox/Main/include/VirtualBoxImpl.h
+++ b/src/VBox/Main/include/VirtualBoxImpl.h
@@ -140,6 +140,7 @@ public:
 
     void i_onSnapshotTaken(const Guid &aMachineId, const Guid &aSnapshotId);
     void i_onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapshotId);
+    void i_onSnapshotRestored(const Guid &aMachineId, const Guid &aSnapshotId);
     void i_onSnapshotChange(const Guid &aMachineId, const Guid &aSnapshotId);
     void i_onGuestPropertyChange(const Guid &aMachineId, IN_BSTR aName, IN_BSTR aValue,
                                  IN_BSTR aFlags);
diff --git a/src/VBox/Main/src-all/Global.cpp b/src/VBox/Main/src-all/Global.cpp
index 3061b32..78a4fe8 100644
--- a/src/VBox/Main/src-all/Global.cpp
+++ b/src/VBox/Main/src-all/Global.cpp
@@ -6,7 +6,7 @@
  */
 
 /*
- * Copyright (C) 2008-2013 Oracle Corporation
+ * Copyright (C) 2008-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -447,9 +447,11 @@ Global::stringifyMachineState(MachineState_T aState)
         case MachineState_FaultTolerantSyncing: return "FaultTolerantSyncing";
         case MachineState_DeletingSnapshotOnline: return "DeletingSnapshotOnline";
         case MachineState_DeletingSnapshotPaused: return "DeletingSnapshotPaused";
+        case MachineState_OnlineSnapshotting:   return "OnlineSnapshotting";
         case MachineState_RestoringSnapshot:    return "RestoringSnapshot";
         case MachineState_DeletingSnapshot:     return "DeletingSnapshot";
         case MachineState_SettingUp:            return "SettingUp";
+        case MachineState_Snapshotting:         return "Snapshotting";
         default:
         {
             AssertMsgFailed(("%d (%#x)\n", aState, aState));
@@ -512,6 +514,7 @@ Global::stringifyReason(Reason_T aReason)
         case Reason_HostSuspend:      return "host suspend";
         case Reason_HostResume:       return "host resume";
         case Reason_HostBatteryLow:   return "host battery low";
+        case Reason_Snapshot:         return "snapshot";
         default:
         {
             AssertMsgFailed(("%d (%#x)\n", aReason, aReason));
diff --git a/src/VBox/Main/src-all/ProgressImpl.cpp b/src/VBox/Main/src-all/ProgressImpl.cpp
index e7d2b3b..bbdc9aa 100644
--- a/src/VBox/Main/src-all/ProgressImpl.cpp
+++ b/src/VBox/Main/src-all/ProgressImpl.cpp
@@ -355,7 +355,7 @@ void Progress::uninit()
 HRESULT Progress::i_notifyComplete(HRESULT aResultCode)
 {
     HRESULT rc;
-    ComPtr<VirtualBoxErrorInfo> errorInfo;
+    ComPtr<IVirtualBoxErrorInfo> errorInfo;
     if (FAILED(aResultCode))
     {
         /* try to import error info from the current thread */
@@ -363,7 +363,7 @@ HRESULT Progress::i_notifyComplete(HRESULT aResultCode)
         ComPtr<IErrorInfo> err;
         rc = ::GetErrorInfo(0, err.asOutParam());
         if (rc == S_OK && err)
-            rc = err.queryInterfaceTo(mErrorInfo.asOutParam());
+            rc = err.queryInterfaceTo(errorInfo.asOutParam());
 #else /* !defined(VBOX_WITH_XPCOM) */
         nsCOMPtr<nsIExceptionService> es;
         es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
diff --git a/src/VBox/Main/src-all/SecretKeyStore.cpp b/src/VBox/Main/src-all/SecretKeyStore.cpp
new file mode 100644
index 0000000..18542b4
--- /dev/null
+++ b/src/VBox/Main/src-all/SecretKeyStore.cpp
@@ -0,0 +1,228 @@
+/* $Id: SecretKeyStore.cpp $ */
+/** @file
+ * Main - Secret key interface.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/err.h>
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/memsafer.h>
+
+#include "SecretKeyStore.h"
+
+SecretKey::SecretKey(const uint8_t *pbKey, size_t cbKey, bool fKeyBufNonPageable)
+{
+    m_cRefs            = 0;
+    m_fRemoveOnSuspend = false;
+    m_cUsers           = 0;
+    m_cbKey            = cbKey;
+
+    int rc = RTMemSaferAllocZEx((void **)&this->m_pbKey, cbKey,
+                                fKeyBufNonPageable ? RTMEMSAFER_F_REQUIRE_NOT_PAGABLE : 0);
+    if (RT_SUCCESS(rc))
+    {
+        memcpy(this->m_pbKey, pbKey, cbKey);
+
+        /* Scramble content to make retrieving the key more difficult. */
+        rc = RTMemSaferScramble(this->m_pbKey, cbKey);
+    }
+    else
+        throw rc;
+}
+
+SecretKey::~SecretKey()
+{
+    Assert(!m_cRefs);
+
+    RTMemSaferFree(m_pbKey, m_cbKey);
+    m_cRefs = 0;
+    m_pbKey = NULL;
+    m_cbKey = 0;
+    m_fRemoveOnSuspend = false;
+    m_cUsers = 0;
+}
+
+uint32_t SecretKey::retain()
+{
+    uint32_t cRefs = ASMAtomicIncU32(&m_cRefs);
+    if (cRefs == 1)
+    {
+        int rc = RTMemSaferUnscramble(m_pbKey, m_cbKey);
+        AssertRC(rc);
+    }
+
+    return cRefs;
+}
+
+uint32_t SecretKey::release()
+{
+    uint32_t cRefs = ASMAtomicDecU32(&m_cRefs);
+    if (!cRefs)
+    {
+        int rc = RTMemSaferScramble(m_pbKey, m_cbKey);
+        AssertRC(rc);
+    }
+
+    return cRefs;
+}
+
+uint32_t SecretKey::refCount()
+{
+    return m_cRefs;
+}
+
+int SecretKey::setUsers(uint32_t cUsers)
+{
+    m_cUsers = cUsers;
+    return VINF_SUCCESS;
+}
+
+uint32_t SecretKey::getUsers()
+{
+    return m_cUsers;
+}
+
+int SecretKey::setRemoveOnSuspend(bool fRemoveOnSuspend)
+{
+    m_fRemoveOnSuspend = fRemoveOnSuspend;
+    return VINF_SUCCESS;
+}
+
+bool SecretKey::getRemoveOnSuspend()
+{
+    return m_fRemoveOnSuspend;
+}
+
+const void *SecretKey::getKeyBuffer()
+{
+    AssertReturn(m_cRefs > 0, NULL);
+    return m_pbKey;
+}
+
+size_t SecretKey::getKeySize()
+{
+    return m_cbKey;
+}
+
+SecretKeyStore::SecretKeyStore(bool fKeyBufNonPageable)
+{
+    m_fKeyBufNonPageable = fKeyBufNonPageable;
+}
+
+SecretKeyStore::~SecretKeyStore()
+{
+    int rc = deleteAllSecretKeys(false /* fSuspend */, true /* fForce */);
+    AssertRC(rc);
+}
+
+int SecretKeyStore::addSecretKey(const com::Utf8Str &strKeyId, const uint8_t *pbKey, size_t cbKey)
+{
+    /* Check that the ID is not existing already. */
+    SecretKeyMap::const_iterator it = m_mapSecretKeys.find(strKeyId);
+    if (it != m_mapSecretKeys.end())
+        return VERR_ALREADY_EXISTS;
+
+    try
+    {
+        SecretKey *pKey = new SecretKey(pbKey, cbKey, m_fKeyBufNonPageable);
+
+        m_mapSecretKeys.insert(std::make_pair(strKeyId, pKey));
+    }
+    catch (int rc)
+    {
+        return rc;
+    }
+
+    return VINF_SUCCESS;
+}
+
+int SecretKeyStore::deleteSecretKey(const com::Utf8Str &strKeyId)
+{
+    SecretKeyMap::iterator it = m_mapSecretKeys.find(strKeyId);
+    if (it == m_mapSecretKeys.end())
+        return VERR_NOT_FOUND;
+
+    SecretKey *pKey = it->second;
+    if (pKey->refCount() != 0)
+        return VERR_RESOURCE_IN_USE;
+
+    m_mapSecretKeys.erase(it);
+    delete pKey;
+
+    return VINF_SUCCESS;
+}
+
+int SecretKeyStore::retainSecretKey(const com::Utf8Str &strKeyId, SecretKey **ppKey)
+{
+    SecretKeyMap::const_iterator it = m_mapSecretKeys.find(strKeyId);
+    if (it == m_mapSecretKeys.end())
+        return VERR_NOT_FOUND;
+
+    SecretKey *pKey = it->second;
+    pKey->retain();
+
+    *ppKey = pKey;
+
+    return VINF_SUCCESS;
+}
+
+int SecretKeyStore::releaseSecretKey(const com::Utf8Str &strKeyId)
+{
+    SecretKeyMap::const_iterator it = m_mapSecretKeys.find(strKeyId);
+    if (it == m_mapSecretKeys.end())
+        return VERR_NOT_FOUND;
+
+    SecretKey *pKey = it->second;
+    pKey->release();
+    return VINF_SUCCESS;
+}
+
+int SecretKeyStore::deleteAllSecretKeys(bool fSuspend, bool fForce)
+{
+    /* First check whether a key is still in use. */
+    if (!fForce)
+    {
+        for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
+             it != m_mapSecretKeys.end();
+             it++)
+        {
+            SecretKey *pKey = it->second;
+            if (   pKey->refCount()
+                && (   (   pKey->getRemoveOnSuspend()
+                        && fSuspend)
+                    || !fSuspend))
+                return VERR_RESOURCE_IN_USE;
+        }
+    }
+
+    SecretKeyMap::iterator it = m_mapSecretKeys.begin();
+    while (it != m_mapSecretKeys.end())
+    {
+        SecretKey *pKey = it->second;
+        if (   pKey->getRemoveOnSuspend()
+            || !fSuspend)
+        {
+            AssertMsg(!pKey->refCount(), ("No one should access the stored key at this point anymore!\n"));
+            delete pKey;
+            m_mapSecretKeys.erase(it++);
+        }
+        else
+            it++;
+    }
+
+    return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/Main/src-all/win/comregister.cmd b/src/VBox/Main/src-all/win/comregister.cmd
index 3a6bf18..2ef4ac4 100644
--- a/src/VBox/Main/src-all/win/comregister.cmd
+++ b/src/VBox/Main/src-all/win/comregister.cmd
@@ -6,7 +6,7 @@ REM (both inproc and out-of-process)
 REM
 
 REM
-REM Copyright (C) 2006-2014 Oracle Corporation
+REM Copyright (C) 2006-2015 Oracle Corporation
 REM
 REM This file is part of VirtualBox Open Source Edition (OSE), as
 REM available from http://www.virtualbox.org. This file is free software;
@@ -21,8 +21,7 @@ setlocal
 
 REM Check if the current user is an administrator. Otherwise
 REM all the COM registration will fail silently.
-NET FILE 1>NUL 2>NUL & IF ERRORLEVEL 1 ^
-    (ECHO Must be run as Administrator. Exiting.) & GOTO end
+NET FILE 1>NUL 2>NUL & IF ERRORLEVEL 1 (ECHO Must be run as Administrator. Exiting.) & GOTO end
 
 REM
 REM Figure out where the script lives first, so that we can invoke the
diff --git a/src/VBox/Main/src-client/ConsoleImpl.cpp b/src/VBox/Main/src-client/ConsoleImpl.cpp
index d83d61a..3065360 100644
--- a/src/VBox/Main/src-client/ConsoleImpl.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl.cpp
@@ -163,7 +163,6 @@ struct VMTask
           mConsoleCaller(aConsole),
           mProgress(aProgress),
           mServerProgress(aServerProgress),
-          mpUVM(NULL),
           mRC(E_FAIL),
           mpSafeVMPtr(NULL)
     {
@@ -174,9 +173,7 @@ struct VMTask
         if (aUsesVMPtr)
         {
             mpSafeVMPtr = new Console::SafeVMPtr(aConsole);
-            if (mpSafeVMPtr->isOk())
-                mpUVM = mpSafeVMPtr->rawUVM();
-            else
+            if (!mpSafeVMPtr->isOk())
                 mRC = mpSafeVMPtr->rc();
         }
     }
@@ -204,33 +201,12 @@ struct VMTask
     const ComObjPtr<Progress>   mProgress;
     Utf8Str                     mErrorMsg;
     const ComPtr<IProgress>     mServerProgress;
-    PUVM                        mpUVM;
 
 private:
     HRESULT                     mRC;
     Console::SafeVMPtr         *mpSafeVMPtr;
 };
 
-struct VMTakeSnapshotTask : public VMTask
-{
-    VMTakeSnapshotTask(Console *aConsole,
-                       Progress *aProgress,
-                       IN_BSTR aName,
-                       IN_BSTR aDescription)
-        : VMTask(aConsole, aProgress, NULL /* aServerProgress */,
-                 false /* aUsesVMPtr */),
-          bstrName(aName),
-          bstrDescription(aDescription),
-          lastMachineState(MachineState_Null)
-    {}
-
-    Bstr                    bstrName,
-                            bstrDescription;
-    Bstr                    bstrSavedStateFile;         // received from BeginTakeSnapshot()
-    MachineState_T          lastMachineState;
-    bool                    fTakingSnapshotOnline;
-    ULONG                   ulMemSize;
-};
 
 struct VMPowerUpTask : public VMTask
 {
@@ -265,27 +241,6 @@ struct VMPowerDownTask : public VMTask
     {}
 };
 
-struct VMSaveTask : public VMTask
-{
-    VMSaveTask(Console *aConsole,
-               const ComPtr<IProgress> &aServerProgress,
-               const Utf8Str &aSavedStateFile,
-               MachineState_T aMachineStateBefore,
-               Reason_T aReason)
-        : VMTask(aConsole, NULL /* aProgress */, aServerProgress,
-                 true /* aUsesVMPtr */),
-          mSavedStateFile(aSavedStateFile),
-          mMachineStateBefore(aMachineStateBefore),
-          mReason(aReason)
-    {}
-
-    Utf8Str mSavedStateFile;
-    /* The local machine state we had before. Required if something fails */
-    MachineState_T mMachineStateBefore;
-    /* The reason for saving state */
-    Reason_T mReason;
-};
-
 // Handler for global events
 ////////////////////////////////////////////////////////////////////////////////
 inline static const char *networkAdapterTypeToName(NetworkAdapterType_T adapterType);
@@ -429,6 +384,7 @@ Console::Console()
     , mUsbCardReader(NULL)
 #endif
     , mBusMgr(NULL)
+    , m_pKeyStore(NULL)
     , mpIfSecKey(NULL)
     , mpIfSecKeyHlp(NULL)
     , mVMStateChangeCallbackDisabled(false)
@@ -595,14 +551,6 @@ HRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl, Loc
         for (ULONG slot = 0; slot < maxNetworkAdapters; ++slot)
             meAttachmentType[slot] = NetworkAttachmentType_Null;
 
-        // VirtualBox 4.0: We no longer initialize the VMMDev instance here,
-        // which starts the HGCM thread. Instead, this is now done in the
-        // power-up thread when a VM is actually being powered up to avoid
-        // having HGCM threads all over the place every time a session is
-        // opened, even if that session will not run a VM.
-        //     unconst(m_pVMMDev) = new VMMDev(this);
-        //     AssertReturn(mVMMDev, E_FAIL);
-
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
         unconst(mAudioVRDE) = new AudioVRDE(this);
         AssertReturn(mAudioVRDE, E_FAIL);
@@ -626,6 +574,9 @@ HRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl, Loc
         AssertReturn(mUsbCardReader, E_FAIL);
 #endif
 
+        unconst(m_pKeyStore) = new SecretKeyStore(true /* fKeyBufNonPageable */);
+        AssertReturn(m_pKeyStore, E_FAIL);
+
         /* VirtualBox events registration. */
         {
             ComPtr<IEventSource> pES;
@@ -767,6 +718,12 @@ void Console::uninit()
         mBusMgr = NULL;
     }
 
+    if (m_pKeyStore)
+    {
+        delete m_pKeyStore;
+        unconst(m_pKeyStore) = NULL;
+    }
+
     m_mapGlobalSharedFolders.clear();
     m_mapMachineSharedFolders.clear();
     m_mapSharedFolders.clear();             // console instances
@@ -774,12 +731,6 @@ void Console::uninit()
     mRemoteUSBDevices.clear();
     mUSBDevices.clear();
 
-    for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
-         it != m_mapSecretKeys.end();
-         it++)
-        delete it->second;
-    m_mapSecretKeys.clear();
-
     if (mVRDEServerInfo)
     {
         mVRDEServerInfo->uninit();
@@ -2101,17 +2052,13 @@ HRESULT Console::setUseHostClipboard(BOOL aUseHostClipboard)
 
 HRESULT Console::powerUp(ComPtr<IProgress> &aProgress)
 {
-    ComObjPtr<IProgress> pProgress;
-    i_powerUp(pProgress.asOutParam(), false /* aPaused */);
-    pProgress.queryInterfaceTo(aProgress.asOutParam());
+    i_powerUp(aProgress.asOutParam(), false /* aPaused */);
     return S_OK;
 }
 
 HRESULT Console::powerUpPaused(ComPtr<IProgress> &aProgress)
 {
-    ComObjPtr<IProgress> pProgress;
-    i_powerUp(pProgress.asOutParam(), true /* aPaused */);
-    pProgress.queryInterfaceTo(aProgress.asOutParam());
+    i_powerUp(aProgress.asOutParam(), true /* aPaused */);
     return S_OK;
 }
 
@@ -2129,6 +2076,16 @@ HRESULT Console::powerDown(ComPtr<IProgress> &aProgress)
         case MachineState_Stuck:
             break;
 
+        /* Try cancel the save state. */
+        case MachineState_Saving:
+            if (!mptrCancelableProgress.isNull())
+            {
+                HRESULT hrc = mptrCancelableProgress->Cancel();
+                if (SUCCEEDED(hrc))
+                    break;
+            }
+            return setError(VBOX_E_INVALID_VM_STATE, tr("Cannot power down at this point during a save state"));
+
         /* Try cancel the teleportation. */
         case MachineState_Teleporting:
         case MachineState_TeleportingPausedVM:
@@ -2140,6 +2097,16 @@ HRESULT Console::powerDown(ComPtr<IProgress> &aProgress)
             }
             return setError(VBOX_E_INVALID_VM_STATE, tr("Cannot power down at this point in a teleportation"));
 
+        /* Try cancel the online snapshot. */
+        case MachineState_OnlineSnapshotting:
+            if (!mptrCancelableProgress.isNull())
+            {
+                HRESULT hrc = mptrCancelableProgress->Cancel();
+                if (SUCCEEDED(hrc))
+                    break;
+            }
+            return setError(VBOX_E_INVALID_VM_STATE, tr("Cannot power down at this point in an online snapshot"));
+
         /* Try cancel the live snapshot. */
         case MachineState_LiveSnapshotting:
             if (!mptrCancelableProgress.isNull())
@@ -2534,7 +2501,14 @@ HRESULT Console::resume()
 {
     LogFlowThisFuncEnter();
 
-    HRESULT rc = i_resume(Reason_Unspecified);
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    if (mMachineState != MachineState_Paused)
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Cannot resume the machine as it is not paused (machine state: %s)"),
+                        Global::stringifyMachineState(mMachineState));
+
+    HRESULT rc = i_resume(Reason_Unspecified, alock);
 
     LogFlowThisFunc(("rc=%Rhrc\n", rc));
     LogFlowThisFuncLeave();
@@ -2718,55 +2692,6 @@ HRESULT Console::sleepButton()
     return rc;
 }
 
-HRESULT Console::saveState(ComPtr<IProgress> &aProgress)
-{
-    LogFlowThisFuncEnter();
-    ComObjPtr<IProgress> pProgress;
-
-    HRESULT rc = i_saveState(Reason_Unspecified, pProgress.asOutParam());
-    pProgress.queryInterfaceTo(aProgress.asOutParam());
-
-    LogFlowThisFunc(("rc=%Rhrc\n", rc));
-    LogFlowThisFuncLeave();
-    return rc;
-}
-
-HRESULT Console::adoptSavedState(const com::Utf8Str &aSavedStateFile)
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (   mMachineState != MachineState_PoweredOff
-        && mMachineState != MachineState_Teleported
-        && mMachineState != MachineState_Aborted
-       )
-        return setError(VBOX_E_INVALID_VM_STATE,
-            tr("Cannot adopt the saved machine state as the machine is not in Powered Off, Teleported or Aborted state (machine state: %s)"),
-            Global::stringifyMachineState(mMachineState));
-
-    return mControl->AdoptSavedState(Bstr(aSavedStateFile.c_str()).raw());
-}
-
-HRESULT Console::discardSavedState(BOOL aFRemoveFile)
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (mMachineState != MachineState_Saved)
-        return setError(VBOX_E_INVALID_VM_STATE,
-            tr("Cannot delete the machine state as the machine is not in the saved state (machine state: %s)"),
-            Global::stringifyMachineState(mMachineState));
-
-    HRESULT rc = mControl->SetRemoveSavedStateFile(aFRemoveFile);
-    if (FAILED(rc)) return rc;
-
-    /*
-     * Saved -> PoweredOff transition will be detected in the SessionMachine
-     * and properly handled.
-     */
-    rc = i_setMachineState(MachineState_PoweredOff);
-
-    return rc;
-}
-
 /** read the value of a LED. */
 inline uint32_t readAndClearLed(PPDMLED pLed)
 {
@@ -3152,212 +3077,6 @@ HRESULT Console::removeSharedFolder(const com::Utf8Str &aName)
     return rc;
 }
 
-HRESULT Console::takeSnapshot(const com::Utf8Str &aName,
-                              const com::Utf8Str &aDescription,
-                              ComPtr<IProgress> &aProgress)
-{
-    LogFlowThisFuncEnter();
-
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-    LogFlowThisFunc(("aName='%s' mMachineState=%d\n", aName.c_str(), mMachineState));
-
-    if (Global::IsTransient(mMachineState))
-        return setError(VBOX_E_INVALID_VM_STATE,
-                        tr("Cannot take a snapshot of the machine while it is changing the state (machine state: %s)"),
-                        Global::stringifyMachineState(mMachineState));
-
-    HRESULT rc = S_OK;
-
-    /* prepare the progress object:
-       a) count the no. of hard disk attachments to get a matching no. of progress sub-operations */
-    ULONG cOperations = 2;              // always at least setting up + finishing up
-    ULONG ulTotalOperationsWeight = 2;  // one each for setting up + finishing up
-    SafeIfaceArray<IMediumAttachment> aMediumAttachments;
-    rc = mMachine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(aMediumAttachments));
-    if (FAILED(rc))
-        return setError(rc, tr("Cannot get medium attachments of the machine"));
-
-    ULONG ulMemSize;
-    rc = mMachine->COMGETTER(MemorySize)(&ulMemSize);
-    if (FAILED(rc))
-        return rc;
-
-    for (size_t i = 0;
-         i < aMediumAttachments.size();
-         ++i)
-    {
-        DeviceType_T type;
-        rc = aMediumAttachments[i]->COMGETTER(Type)(&type);
-        if (FAILED(rc))
-            return rc;
-
-        if (type == DeviceType_HardDisk)
-        {
-            ++cOperations;
-
-            // assume that creating a diff image takes as long as saving a 1MB state
-            // (note, the same value must be used in SessionMachine::BeginTakingSnapshot() on the server!)
-            ulTotalOperationsWeight += 1;
-        }
-    }
-
-    // b) one extra sub-operations for online snapshots OR offline snapshots that have a saved state (needs to be copied)
-    bool const fTakingSnapshotOnline = Global::IsOnline(mMachineState);
-
-    LogFlowFunc(("fTakingSnapshotOnline = %d, mMachineState = %d\n", fTakingSnapshotOnline, mMachineState));
-
-    if (fTakingSnapshotOnline)
-    {
-        ++cOperations;
-        ulTotalOperationsWeight += ulMemSize;
-    }
-
-    // finally, create the progress object
-    ComObjPtr<Progress> pProgress;
-    pProgress.createObject();
-    rc = pProgress->init(static_cast<IConsole *>(this),
-                         Bstr(tr("Taking a snapshot of the virtual machine")).raw(),
-                            (mMachineState >= MachineState_FirstOnline)
-                         && (mMachineState <= MachineState_LastOnline) /* aCancelable */,
-                         cOperations,
-                         ulTotalOperationsWeight,
-                         Bstr(tr("Setting up snapshot operation")).raw(),      // first sub-op description
-                         1);        // ulFirstOperationWeight
-
-    if (FAILED(rc))
-        return rc;
-
-    VMTakeSnapshotTask *pTask;
-    if (!(pTask = new VMTakeSnapshotTask(this, pProgress, Bstr(aName).raw(), Bstr(aDescription).raw())))
-        return E_OUTOFMEMORY;
-
-    Assert(pTask->mProgress);
-
-    try
-    {
-        mptrCancelableProgress = pProgress;
-
-        /*
-         * If we fail here it means a PowerDown() call happened on another
-         * thread while we were doing Pause() (which releases the Console lock).
-         * We assign PowerDown() a higher precedence than TakeSnapshot(),
-         * therefore just return the error to the caller.
-         */
-        rc = pTask->rc();
-        if (FAILED(rc)) throw rc;
-
-        pTask->ulMemSize = ulMemSize;
-
-        /* memorize the current machine state */
-        pTask->lastMachineState = mMachineState;
-        pTask->fTakingSnapshotOnline = fTakingSnapshotOnline;
-
-        int vrc = RTThreadCreate(NULL,
-                                 Console::i_fntTakeSnapshotWorker,
-                                 (void *)pTask,
-                                 0,
-                                 RTTHREADTYPE_MAIN_WORKER,
-                                 0,
-                                 "TakeSnap");
-        if (FAILED(vrc))
-            throw setError(E_FAIL,
-                           tr("Could not create VMTakeSnap thread (%Rrc)"),
-                           vrc);
-
-        pTask->mProgress.queryInterfaceTo(aProgress.asOutParam());
-    }
-    catch (HRESULT erc)
-    {
-        delete pTask;
-        rc = erc;
-        mptrCancelableProgress.setNull();
-    }
-
-    LogFlowThisFunc(("rc=%Rhrc\n", rc));
-    LogFlowThisFuncLeave();
-    return rc;
-}
-
-HRESULT Console::deleteSnapshot(const com::Guid &aId, ComPtr<IProgress> &aProgress)
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (Global::IsTransient(mMachineState))
-        return setError(VBOX_E_INVALID_VM_STATE,
-                        tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
-                        Global::stringifyMachineState(mMachineState));
-    ComObjPtr<IProgress> iProgress;
-    MachineState_T machineState = MachineState_Null;
-    HRESULT rc = mControl->DeleteSnapshot((IConsole *)this, Bstr(aId.toString()).raw(), Bstr(aId.toString()).raw(),
-                                          FALSE /* fDeleteAllChildren */, &machineState, iProgress.asOutParam());
-    if (FAILED(rc)) return rc;
-    iProgress.queryInterfaceTo(aProgress.asOutParam());
-
-    i_setMachineStateLocally(machineState);
-    return S_OK;
-}
-
-HRESULT Console::deleteSnapshotAndAllChildren(const com::Guid &aId, ComPtr<IProgress> &aProgress)
-
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (Global::IsTransient(mMachineState))
-        return setError(VBOX_E_INVALID_VM_STATE,
-                        tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
-                        Global::stringifyMachineState(mMachineState));
-
-    ComObjPtr<IProgress> iProgress;
-    MachineState_T machineState = MachineState_Null;
-    HRESULT rc = mControl->DeleteSnapshot((IConsole *)this, Bstr(aId.toString()).raw(), Bstr(aId.toString()).raw(),
-                                          TRUE /* fDeleteAllChildren */, &machineState, iProgress.asOutParam());
-    if (FAILED(rc)) return rc;
-    iProgress.queryInterfaceTo(aProgress.asOutParam());
-
-    i_setMachineStateLocally(machineState);
-    return S_OK;
-}
-
-HRESULT Console::deleteSnapshotRange(const com::Guid &aStartId, const com::Guid &aEndId, ComPtr<IProgress> &aProgress)
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (Global::IsTransient(mMachineState))
-        return setError(VBOX_E_INVALID_VM_STATE,
-                        tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
-                        Global::stringifyMachineState(mMachineState));
-
-    ComObjPtr<IProgress> iProgress;
-    MachineState_T machineState = MachineState_Null;
-    HRESULT rc = mControl->DeleteSnapshot((IConsole *)this, Bstr(aStartId.toString()).raw(), Bstr(aEndId.toString()).raw(),
-                                          FALSE /* fDeleteAllChildren */, &machineState, iProgress.asOutParam());
-    if (FAILED(rc)) return rc;
-    iProgress.queryInterfaceTo(aProgress.asOutParam());
-
-    i_setMachineStateLocally(machineState);
-    return S_OK;
-}
-
-HRESULT Console::restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot, ComPtr<IProgress> &aProgress)
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (Global::IsOnlineOrTransient(mMachineState))
-        return setError(VBOX_E_INVALID_VM_STATE,
-                        tr("Cannot delete the current state of the running machine (machine state: %s)"),
-                        Global::stringifyMachineState(mMachineState));
-
-    ISnapshot* iSnapshot = aSnapshot;
-    ComObjPtr<IProgress> iProgress;
-    MachineState_T machineState = MachineState_Null;
-    HRESULT rc = mControl->RestoreSnapshot((IConsole*)this, iSnapshot, &machineState, iProgress.asOutParam());
-    if (FAILED(rc)) return rc;
-    iProgress.queryInterfaceTo(aProgress.asOutParam());
-
-    i_setMachineStateLocally(machineState);
-    return S_OK;
-}
-
 HRESULT Console::addDiskEncryptionPassword(const com::Utf8Str &aId, const com::Utf8Str &aPassword,
                                            BOOL aClearOnSuspend)
 {
@@ -3367,30 +3086,25 @@ HRESULT Console::addDiskEncryptionPassword(const com::Utf8Str &aId, const com::U
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    /* Check that the ID is not existing already. */
-    SecretKeyMap::const_iterator it = m_mapSecretKeys.find(aId);
-    if (it != m_mapSecretKeys.end())
-        return setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists"));
-
     HRESULT hrc = S_OK;
     size_t cbKey = aPassword.length() + 1; /* Include terminator */
-    uint8_t *pbKey = NULL;
-    int rc = RTMemSaferAllocZEx((void **)&pbKey, cbKey, RTMEMSAFER_F_REQUIRE_NOT_PAGABLE);
+    const uint8_t *pbKey = (const uint8_t *)aPassword.c_str();
+
+    int rc = m_pKeyStore->addSecretKey(aId, pbKey, cbKey);
     if (RT_SUCCESS(rc))
     {
         unsigned cDisksConfigured = 0;
-        memcpy(pbKey, aPassword.c_str(), cbKey);
-
-        /* Scramble content to make retrieving the key more difficult. */
-        rc = RTMemSaferScramble(pbKey, cbKey);
-        AssertRC(rc);
-        SecretKey *pKey = new SecretKey(pbKey, cbKey, !!aClearOnSuspend);
-        /* Add the key to the map */
-        m_mapSecretKeys.insert(std::make_pair(aId, pKey));
+
         hrc = i_configureEncryptionForDisk(aId, &cDisksConfigured);
         if (SUCCEEDED(hrc))
         {
-            pKey->m_cDisks = cDisksConfigured;
+            SecretKey *pKey = NULL;
+            rc = m_pKeyStore->retainSecretKey(aId, &pKey);
+            AssertRCReturn(rc, E_FAIL);
+
+            pKey->setUsers(cDisksConfigured);
+            pKey->setRemoveOnSuspend(!!aClearOnSuspend);
+            m_pKeyStore->releaseSecretKey(aId);
             m_cDisksPwProvided += cDisksConfigured;
 
             if (   m_cDisksPwProvided == m_cDisksEncrypted
@@ -3410,11 +3124,13 @@ HRESULT Console::addDiskEncryptionPassword(const com::Utf8Str &aId, const com::U
                              vrc);
             }
         }
-        else
-            m_mapSecretKeys.erase(aId);
     }
+    else if (rc == VERR_ALREADY_EXISTS)
+        hrc = setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists"));
+    else if (rc == VERR_NO_MEMORY)
+        hrc = setError(E_FAIL, tr("Failed to allocate enough secure memory for the key"));
     else
-        return setError(E_FAIL, tr("Failed to allocate secure memory for the password (%Rrc)"), rc);
+        hrc = setError(E_FAIL, tr("Unknown error happened while adding a password (%Rrc)"), rc);
 
     return hrc;
 }
@@ -3436,36 +3152,20 @@ HRESULT Console::addDiskEncryptionPasswords(const std::vector<com::Utf8Str> &aId
     /* Check that the IDs do not exist already before changing anything. */
     for (unsigned i = 0; i < aIds.size(); i++)
     {
-        SecretKeyMap::const_iterator it = m_mapSecretKeys.find(aIds[i]);
-        if (it != m_mapSecretKeys.end())
+        SecretKey *pKey = NULL;
+        int rc = m_pKeyStore->retainSecretKey(aIds[i], &pKey);
+        if (rc != VERR_NOT_FOUND)
+        {
+            AssertPtr(pKey);
+            if (pKey)
+                pKey->release();
             return setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists"));
+        }
     }
 
     for (unsigned i = 0; i < aIds.size(); i++)
     {
-        size_t cbKey = aPasswords[i].length() + 1; /* Include terminator */
-        uint8_t *pbKey = NULL;
-        int rc = RTMemSaferAllocZEx((void **)&pbKey, cbKey, RTMEMSAFER_F_REQUIRE_NOT_PAGABLE);
-        if (RT_SUCCESS(rc))
-        {
-            unsigned cDisksConfigured = 0;
-            memcpy(pbKey, aPasswords[i].c_str(), cbKey);
-
-            /* Scramble content to make retrieving the key more difficult. */
-            rc = RTMemSaferScramble(pbKey, cbKey);
-            AssertRC(rc);
-            SecretKey *pKey = new SecretKey(pbKey, cbKey, !!aClearOnSuspend);
-            /* Add the key to the map */
-            m_mapSecretKeys.insert(std::make_pair(aIds[i], pKey));
-            hrc = i_configureEncryptionForDisk(aIds[i], &cDisksConfigured);
-            if (FAILED(hrc))
-                m_mapSecretKeys.erase(aIds[i]);
-            else
-                pKey->m_cDisks = cDisksConfigured;
-        }
-        else
-            hrc = setError(E_FAIL, tr("Failed to allocate secure memory for the password (%Rrc)"), rc);
-
+        hrc = addDiskEncryptionPassword(aIds[i], aPasswords[i], aClearOnSuspend);
         if (FAILED(hrc))
         {
             /*
@@ -3483,23 +3183,6 @@ HRESULT Console::addDiskEncryptionPasswords(const std::vector<com::Utf8Str> &aId
         }
     }
 
-    if (   SUCCEEDED(hrc)
-        && m_cDisksPwProvided == m_cDisksEncrypted
-        && mMachineState == MachineState_Paused)
-    {
-        /* get the VM handle. */
-        SafeVMPtr ptrVM(this);
-        if (!ptrVM.isOk())
-            return ptrVM.rc();
-
-        alock.release();
-        int vrc = VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_RECONFIG);
-
-        hrc = RT_SUCCESS(vrc) ? S_OK :
-                setError(VBOX_E_VM_ERROR,
-                         tr("Could not resume the machine execution (%Rrc)"), vrc);
-    }
-
     return hrc;
 }
 
@@ -3510,17 +3193,21 @@ HRESULT Console::removeDiskEncryptionPassword(const com::Utf8Str &aId)
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    SecretKeyMap::iterator it = m_mapSecretKeys.find(aId);
-    if (it == m_mapSecretKeys.end())
-        return setError(VBOX_E_OBJECT_NOT_FOUND, tr("A password with the given ID does not exist"));
-
-    SecretKey *pKey = it->second;
-    if (pKey->m_cRefs)
-        return setError(VBOX_E_OBJECT_IN_USE, tr("The password is still in use by the VM"));
-
-    m_cDisksPwProvided -= pKey->m_cDisks;
-    m_mapSecretKeys.erase(it);
-    delete pKey;
+    SecretKey *pKey = NULL;
+    int rc = m_pKeyStore->retainSecretKey(aId, &pKey);
+    if (RT_SUCCESS(rc))
+    {
+        m_cDisksPwProvided -= pKey->getUsers();
+        m_pKeyStore->releaseSecretKey(aId);
+        rc = m_pKeyStore->deleteSecretKey(aId);
+        AssertRCReturn(rc, E_FAIL);
+    }
+    else if (rc == VERR_NOT_FOUND)
+        return setError(VBOX_E_OBJECT_NOT_FOUND, tr("A password with the ID \"%s\" does not exist"),
+                                                 aId.c_str());
+    else
+        return setError(E_FAIL, tr("Failed to remove password with ID \"%s\" (%Rrc)"),
+                                aId.c_str(), rc);
 
     return S_OK;
 }
@@ -3529,24 +3216,13 @@ HRESULT Console::clearAllDiskEncryptionPasswords()
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    /* First check whether a password is still in use. */
-    for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
-        it != m_mapSecretKeys.end();
-        it++)
-    {
-        SecretKey *pKey = it->second;
-        if (pKey->m_cRefs)
-            return setError(VBOX_E_OBJECT_IN_USE, tr("The password with ID \"%s\" is still in use by the VM"),
-                            it->first.c_str());
-    }
+    int rc = m_pKeyStore->deleteAllSecretKeys(false /* fSuspend */, false /* fForce */);
+    if (rc == VERR_RESOURCE_IN_USE)
+        return setError(VBOX_E_OBJECT_IN_USE, tr("A password is still in use by the VM"));
+    else if (RT_FAILURE(rc))
+        return setError(E_FAIL, tr("Deleting all passwords failed (%Rrc)"));
 
-    for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
-        it != m_mapSecretKeys.end();
-        it++)
-        delete it->second;
-    m_mapSecretKeys.clear();
     m_cDisksPwProvided = 0;
-
     return S_OK;
 }
 
@@ -3683,7 +3359,7 @@ HRESULT Console::i_suspendBeforeConfigChange(PUVM pUVM, AutoWriteLock *pAlock, b
                                     COM_IIDOF(IConsole),
                                     getStaticComponentName(),
                                     Utf8StrFmt("Invalid state '%s' for changing medium",
-                                        VMR3GetStateName(enmVMState)),
+                                               VMR3GetStateName(enmVMState)),
                                     false /*aWarning*/,
                                     true /*aLogIt*/);
     }
@@ -5072,20 +4748,24 @@ HRESULT Console::i_consoleParseDiskEncryption(const char *psz, const char **ppsz
                 rc = RTBase64Decode(pszKeyEnc, pbKey, cbKey, NULL, NULL);
                 if (RT_SUCCESS(rc))
                 {
-                    SecretKey *pKey = new SecretKey(pbKey, cbKey, true /* fRemoveOnSuspend */);
-                    /* Add the key to the map */
-                    m_mapSecretKeys.insert(std::make_pair(Utf8Str(pszUuid), pKey));
-                    hrc = i_configureEncryptionForDisk(Utf8Str(pszUuid), NULL);
-                    if (FAILED(hrc))
+                    rc = m_pKeyStore->addSecretKey(Utf8Str(pszUuid), pbKey, cbKey);
+                    if (RT_SUCCESS(rc))
                     {
-                        /* Delete the key from the map. */
-                        m_mapSecretKeys.erase(Utf8Str(pszUuid));
+                        hrc = i_configureEncryptionForDisk(Utf8Str(pszUuid), NULL);
+                        if (FAILED(hrc))
+                        {
+                            /* Delete the key from the map. */
+                            rc = m_pKeyStore->deleteSecretKey(Utf8Str(pszUuid));
+                            AssertRC(rc);
+                        }
                     }
                 }
                 else
                     hrc = setError(E_FAIL,
                                    tr("Failed to decode the key (%Rrc)"),
                                    rc);
+
+                RTMemSaferFree(pbKey, cbKey);
             }
             else
                 hrc = setError(E_FAIL,
@@ -5132,23 +4812,7 @@ HRESULT Console::i_setDiskEncryptionKeys(const Utf8Str &strCfg)
 void Console::i_removeSecretKeysOnSuspend()
 {
     /* Remove keys which are supposed to be removed on a suspend. */
-    SecretKeyMap::iterator it = m_mapSecretKeys.begin();
-    while (it != m_mapSecretKeys.end())
-    {
-        SecretKey *pKey = it->second;
-        if (pKey->m_fRemoveOnSuspend)
-        {
-            /* Unconfigure disk encryption from all attachments associated with this key. */
-            i_clearDiskEncryptionKeysOnAllAttachmentsWithKeyId(it->first);
-
-            AssertMsg(!pKey->m_cRefs, ("No one should access the stored key at this point anymore!\n"));
-            m_cDisksPwProvided -= pKey->m_cDisks;
-            delete pKey;
-            m_mapSecretKeys.erase(it++);
-        }
-        else
-            it++;
-    }
+    int rc = m_pKeyStore->deleteAllSecretKeys(true /* fSuspend */, true /* fForce */);
 }
 
 /**
@@ -5479,7 +5143,7 @@ HRESULT Console::i_onDnDModeChange(DnDMode_T aDnDMode)
 
     HRESULT rc = S_OK;
 
-    /* don't trigger the drag'n'drop mode change if the VM isn't running */
+    /* don't trigger the drag and drop mode change if the VM isn't running */
     SafeVMPtrQuiet ptrVM(this);
     if (ptrVM.isOk())
     {
@@ -6254,8 +5918,8 @@ static int onlineMergeMediumProgress(void *pvUser, unsigned uPercentage)
  * @note Temporarily locks this object for writing. bird: And/or reading?
  */
 HRESULT Console::i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
-                                   ULONG aSourceIdx, ULONG aTargetIdx,
-                                   IProgress *aProgress)
+                                     ULONG aSourceIdx, ULONG aTargetIdx,
+                                     IProgress *aProgress)
 {
     AutoCaller autoCaller(this);
     AssertComRCReturnRC(autoCaller.rc());
@@ -6269,7 +5933,7 @@ HRESULT Console::i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
         return ptrVM.rc();
 
     /* We will need to release the lock before doing the actual merge */
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     /* paranoia - we don't want merges to happen while teleporting etc. */
     switch (mMachineState)
@@ -6345,20 +6009,15 @@ HRESULT Console::i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
     rc = Console::i_convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN);
     AssertComRCReturnRC(rc);
 
-    alock.release();
+    Assert(mMachineState == MachineState_DeletingSnapshotOnline);
 
     /* Pause the VM, as it might have pending IO on this drive */
-    VMSTATE enmVMState = VMR3GetStateU(ptrVM.rawUVM());
-    if (mMachineState == MachineState_DeletingSnapshotOnline)
-    {
-        LogFlowFunc(("Suspending the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Suspend(ptrVM.rawUVM(), VMSUSPENDREASON_RECONFIG);
-        mVMStateChangeCallbackDisabled = false;
-        AssertRCReturn(vrc2, E_FAIL);
-    }
+    bool fResume = false;
+    rc = i_suspendBeforeConfigChange(ptrVM.rawUVM(), &alock, &fResume);
+    if (FAILED(rc))
+        return rc;
 
+    alock.release();
     vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY,
                            (PFNRT)i_reconfigureMediumAttachment, 13,
                            this, ptrVM.rawUVM(), pcszDevice, uInstance, enmBus, fUseHostIOCache,
@@ -6366,20 +6025,8 @@ HRESULT Console::i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
                            aMediumAttachment, mMachineState, &rc);
     /* error handling is after resuming the VM */
 
-    if (mMachineState == MachineState_DeletingSnapshotOnline)
-    {
-        LogFlowFunc(("Resuming the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_RECONFIG);
-        mVMStateChangeCallbackDisabled = false;
-        if (RT_FAILURE(vrc2))
-        {
-            /* too bad, we failed. try to sync the console state with the VMM state */
-            AssertLogRelRC(vrc2);
-            i_vmstateChangeCallback(ptrVM.rawUVM(), VMSTATE_SUSPENDED, enmVMState, this);
-        }
-    }
+    if (fResume)
+        i_resumeAfterConfigChange(ptrVM.rawUVM());
 
     if (RT_FAILURE(vrc))
         return setError(E_FAIL, tr("%Rrc"), vrc);
@@ -6406,17 +6053,12 @@ HRESULT Console::i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
     if (RT_FAILURE(vrc))
         return setError(E_FAIL, tr("Failed to perform an online medium merge (%Rrc)"), vrc);
 
+    alock.acquire();
     /* Pause the VM, as it might have pending IO on this drive */
-    enmVMState = VMR3GetStateU(ptrVM.rawUVM());
-    if (mMachineState == MachineState_DeletingSnapshotOnline)
-    {
-        LogFlowFunc(("Suspending the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Suspend(ptrVM.rawUVM(), VMSUSPENDREASON_RECONFIG);
-        mVMStateChangeCallbackDisabled = false;
-        AssertRCReturn(vrc2, E_FAIL);
-    }
+    rc = i_suspendBeforeConfigChange(ptrVM.rawUVM(), &alock, &fResume);
+    if (FAILED(rc))
+        return rc;
+    alock.release();
 
     /* Update medium chain and state now, so that the VM can continue. */
     rc = mControl->FinishOnlineMergeMedium();
@@ -6428,20 +6070,8 @@ HRESULT Console::i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
                            0 /* uMergeTarget */, aMediumAttachment, mMachineState, &rc);
     /* error handling is after resuming the VM */
 
-    if (mMachineState == MachineState_DeletingSnapshotOnline)
-    {
-        LogFlowFunc(("Resuming the VM...\n"));
-        /* disable the callback to prevent Console-level state change */
-        mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_RECONFIG);
-        mVMStateChangeCallbackDisabled = false;
-        AssertRC(vrc2);
-        if (RT_FAILURE(vrc2))
-        {
-            /* too bad, we failed. try to sync the console state with the VMM state */
-            i_vmstateChangeCallback(ptrVM.rawUVM(), VMSTATE_SUSPENDED, enmVMState, this);
-        }
-    }
+    if (fResume)
+        i_resumeAfterConfigChange(ptrVM.rawUVM());
 
     if (RT_FAILURE(vrc))
         return setError(E_FAIL, tr("%Rrc"), vrc);
@@ -6451,17 +6081,93 @@ HRESULT Console::i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
     return rc;
 }
 
-
-/**
- * Load an HGCM service.
- *
- * Main purpose of this method is to allow extension packs to load HGCM
- * service modules, which they can't, because the HGCM functionality lives
- * in module VBoxC (and ConsoleImpl.cpp is part of it and thus can call it).
- * Extension modules must not link directly against VBoxC, (XP)COM is
- * handling this.
- */
-int Console::i_hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName)
+HRESULT Console::i_reconfigureMediumAttachments(const std::vector<ComPtr<IMediumAttachment> > &aAttachments)
+{
+    HRESULT rc = S_OK;
+
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    /* get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    for (size_t i = 0; i < aAttachments.size(); ++i)
+    {
+        ComPtr<IStorageController> pStorageController;
+        Bstr controllerName;
+        ULONG lInstance;
+        StorageControllerType_T enmController;
+        StorageBus_T enmBus;
+        BOOL fUseHostIOCache;
+
+        /*
+         * We could pass the objects, but then EMT would have to do lots of
+         * IPC (to VBoxSVC) which takes a significant amount of time.
+         * Better query needed values here and pass them.
+         */
+        rc = aAttachments[i]->COMGETTER(Controller)(controllerName.asOutParam());
+        if (FAILED(rc))
+            throw rc;
+
+        rc = mMachine->GetStorageControllerByName(controllerName.raw(),
+                                                  pStorageController.asOutParam());
+        if (FAILED(rc))
+            throw rc;
+
+        rc = pStorageController->COMGETTER(ControllerType)(&enmController);
+        if (FAILED(rc))
+            throw rc;
+        rc = pStorageController->COMGETTER(Instance)(&lInstance);
+        if (FAILED(rc))
+            throw rc;
+        rc = pStorageController->COMGETTER(Bus)(&enmBus);
+        if (FAILED(rc))
+            throw rc;
+        rc = pStorageController->COMGETTER(UseHostIOCache)(&fUseHostIOCache);
+        if (FAILED(rc))
+            throw rc;
+
+        const char *pcszDevice = i_convertControllerTypeToDev(enmController);
+
+        BOOL fBuiltinIOCache;
+        rc = mMachine->COMGETTER(IOCacheEnabled)(&fBuiltinIOCache);
+        if (FAILED(rc))
+            throw rc;
+
+        alock.release();
+
+        IMediumAttachment *pAttachment = aAttachments[i];
+        int vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY,
+                                   (PFNRT)i_reconfigureMediumAttachment, 13,
+                                   this, ptrVM.rawUVM(), pcszDevice, lInstance, enmBus, fUseHostIOCache,
+                                   fBuiltinIOCache, false /* fSetupMerge */, 0 /* uMergeSource */,
+                                   0 /* uMergeTarget */, pAttachment, mMachineState, &rc);
+        if (RT_FAILURE(vrc))
+            throw setError(E_FAIL, tr("%Rrc"), vrc);
+        if (FAILED(rc))
+            throw rc;
+
+        alock.acquire();
+    }
+
+    return rc;
+}
+
+
+/**
+ * Load an HGCM service.
+ *
+ * Main purpose of this method is to allow extension packs to load HGCM
+ * service modules, which they can't, because the HGCM functionality lives
+ * in module VBoxC (and ConsoleImpl.cpp is part of it and thus can call it).
+ * Extension modules must not link directly against VBoxC, (XP)COM is
+ * handling this.
+ */
+int Console::i_hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName)
 {
     /* Everyone seems to delegate all HGCM calls to VMMDev, so stick to this
      * convention. Adds one level of indirection for no obvious reason. */
@@ -6500,7 +6206,7 @@ HRESULT Console::i_pause(Reason_T aReason)
 
         case MachineState_Paused:
         case MachineState_TeleportingPausedVM:
-        case MachineState_Saving:
+        case MachineState_OnlineSnapshotting:
 
         /* Remove any keys which are supposed to be removed on a suspend. */
         if (   aReason == Reason_HostSuspend
@@ -6552,20 +6258,13 @@ HRESULT Console::i_pause(Reason_T aReason)
  * Worker for Console::Resume and internal entry point for resuming a VM for
  * a specific reason.
  */
-HRESULT Console::i_resume(Reason_T aReason)
+HRESULT Console::i_resume(Reason_T aReason, AutoWriteLock &alock)
 {
     LogFlowThisFuncEnter();
 
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (mMachineState != MachineState_Paused)
-        return setError(VBOX_E_INVALID_VM_STATE,
-                        tr("Cannot resume the machine as it is not paused (machine state: %s)"),
-                        Global::stringifyMachineState(mMachineState));
-
     /* get the VM handle. */
     SafeVMPtr ptrVM(this);
     if (!ptrVM.isOk())
@@ -6594,7 +6293,15 @@ HRESULT Console::i_resume(Reason_T aReason)
         VMRESUMEREASON enmReason = VMRESUMEREASON_USER;
         if (aReason == Reason_HostResume)
             enmReason = VMRESUMEREASON_HOST_RESUME;
+        else if (aReason == Reason_Snapshot)
+            enmReason = VMRESUMEREASON_STATE_SAVED;
+
+        // for snapshots: no state change callback, VBoxSVC does everything
+        if (aReason == Reason_Snapshot)
+            mVMStateChangeCallbackDisabled = true;
         vrc = VMR3Resume(ptrVM.rawUVM(), enmReason);
+        if (aReason == Reason_Snapshot)
+            mVMStateChangeCallbackDisabled = false;
     }
 
     HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
@@ -6608,14 +6315,22 @@ HRESULT Console::i_resume(Reason_T aReason)
 }
 
 /**
- * Worker for Console::SaveState and internal entry point for saving state of
- * a VM for a specific reason.
+ * Internal entry point for saving state of a VM for a specific reason. This
+ * method is completely synchronous.
+ *
+ * The machine state is already set appropriately. It is only changed when
+ * saving state actually paused the VM (happens with live snapshots and
+ * teleportation), and in this case reflects the now paused variant.
+ *
+ * @note Locks this object for writing.
  */
-HRESULT Console::i_saveState(Reason_T aReason, IProgress **aProgress)
+HRESULT Console::i_saveState(Reason_T aReason, const ComPtr<IProgress> &aProgress, const Utf8Str &aStateFilePath, bool aPauseVM, bool &aLeftPaused)
 {
     LogFlowThisFuncEnter();
+    aLeftPaused = false;
 
-    CheckComArgOutPointerValid(aProgress);
+    AssertReturn(!aProgress.isNull(), E_INVALIDARG);
+    AssertReturn(!aStateFilePath.isEmpty(), E_INVALIDARG);
 
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -6623,13 +6338,17 @@ HRESULT Console::i_saveState(Reason_T aReason, IProgress **aProgress)
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     LogFlowThisFunc(("mMachineState=%d\n", mMachineState));
-    if (   mMachineState != MachineState_Running
-        && mMachineState != MachineState_Paused)
+    if (   mMachineState != MachineState_Saving
+        && mMachineState != MachineState_LiveSnapshotting
+        && mMachineState != MachineState_OnlineSnapshotting
+        && mMachineState != MachineState_Teleporting
+        && mMachineState != MachineState_TeleportingPausedVM)
     {
         return setError(VBOX_E_INVALID_VM_STATE,
             tr("Cannot save the execution state as the machine is not running or paused (machine state: %s)"),
             Global::stringifyMachineState(mMachineState));
     }
+    bool fContinueAfterwards = mMachineState != MachineState_Saving;
 
     Bstr strDisableSaveState;
     mMachine->GetExtraData(Bstr("VBoxInternal2/DisableSaveState").raw(), strDisableSaveState.asOutParam());
@@ -6640,16 +6359,28 @@ HRESULT Console::i_saveState(Reason_T aReason, IProgress **aProgress)
     if (aReason != Reason_Unspecified)
         LogRel(("Saving state of VM, reason \"%s\"\n", Global::stringifyReason(aReason)));
 
-    /* memorize the current machine state */
-    MachineState_T lastMachineState = mMachineState;
-
-    if (mMachineState == MachineState_Running)
+    /* ensure the directory for the saved state file exists */
     {
-        /* get the VM handle. */
-        SafeVMPtr ptrVM(this);
-        if (!ptrVM.isOk())
-            return ptrVM.rc();
+        Utf8Str dir = aStateFilePath;
+        dir.stripFilename();
+        if (!RTDirExists(dir.c_str()))
+        {
+            int vrc = RTDirCreateFullPath(dir.c_str(), 0700);
+            if (RT_FAILURE(vrc))
+                return setError(VBOX_E_FILE_ERROR,
+                                tr("Could not create a directory '%s' to save the state to (%Rrc)"),
+                                dir.c_str(), vrc);
+        }
+    }
+
+    /* Get the VM handle early, we need it in several places. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
+    bool fPaused = false;
+    if (aPauseVM)
+    {
         /* release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
         alock.release();
         VMSUSPENDREASON enmReason = VMSUSPENDREASON_USER;
@@ -6660,123 +6391,84 @@ HRESULT Console::i_saveState(Reason_T aReason, IProgress **aProgress)
         int vrc = VMR3Suspend(ptrVM.rawUVM(), enmReason);
         alock.acquire();
 
-        HRESULT hrc = S_OK;
         if (RT_FAILURE(vrc))
-            hrc = setError(VBOX_E_VM_ERROR, tr("Could not suspend the machine execution (%Rrc)"), vrc);
-        if (FAILED(hrc))
-            return hrc;
+            return setError(VBOX_E_VM_ERROR, tr("Could not suspend the machine execution (%Rrc)"), vrc);
+        fPaused = true;
     }
 
-    HRESULT rc = S_OK;
-    bool fBeganSavingState = false;
-    bool fTaskCreationFailed = false;
+    LogFlowFunc(("Saving the state to '%s'...\n", aStateFilePath.c_str()));
 
-    do
+    mptrCancelableProgress = aProgress;
+    alock.release();
+    int vrc = VMR3Save(ptrVM.rawUVM(),
+                       aStateFilePath.c_str(),
+                       fContinueAfterwards,
+                       Console::i_stateProgressCallback,
+                       static_cast<IProgress *>(aProgress),
+                       &aLeftPaused);
+    alock.acquire();
+    mptrCancelableProgress.setNull();
+    if (RT_FAILURE(vrc))
     {
-        ComPtr<IProgress> pProgress;
-        Bstr stateFilePath;
-
-        /*
-         * request a saved state file path from the server
-         * (this will set the machine state to Saving on the server to block
-         * others from accessing this machine)
-         */
-        rc = mControl->BeginSavingState(pProgress.asOutParam(),
-                                        stateFilePath.asOutParam());
-        if (FAILED(rc))
-            break;
-
-        fBeganSavingState = true;
-
-        /* sync the state with the server */
-        i_setMachineStateLocally(MachineState_Saving);
-
-        /* ensure the directory for the saved state file exists */
+        if (fPaused)
         {
-            Utf8Str dir = stateFilePath;
-            dir.stripFilename();
-            if (!RTDirExists(dir.c_str()))
-            {
-                int vrc = RTDirCreateFullPath(dir.c_str(), 0700);
-                if (RT_FAILURE(vrc))
-                {
-                    rc = setError(VBOX_E_FILE_ERROR,
-                        tr("Could not create a directory '%s' to save the state to (%Rrc)"),
-                        dir.c_str(), vrc);
-                    break;
-                }
-            }
+            alock.release();
+            VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_STATE_RESTORED);
+            alock.acquire();
         }
+        return setError(E_FAIL, tr("Failed to save the machine state to '%s' (%Rrc)"),
+                        aStateFilePath.c_str(), vrc);
+    }
+    Assert(fContinueAfterwards || !aLeftPaused);
 
-        /* Create a task object early to ensure mpUVM protection is successful. */
-        std::auto_ptr<VMSaveTask> task(new VMSaveTask(this, pProgress,
-                                                      stateFilePath,
-                                                      lastMachineState,
-                                                      aReason));
-        rc = task->rc();
+    if (!fContinueAfterwards)
+    {
         /*
-         * If we fail here it means a PowerDown() call happened on another
-         * thread while we were doing Pause() (which releases the Console lock).
-         * We assign PowerDown() a higher precedence than SaveState(),
-         * therefore just return the error to the caller.
+         * The machine has been successfully saved, so power it down
+         * (vmstateChangeCallback() will set state to Saved on success).
+         * Note: we release the VM caller, otherwise it will deadlock.
          */
-        if (FAILED(rc))
-        {
-            fTaskCreationFailed = true;
-            break;
-        }
+        ptrVM.release();
+        alock.release();
+        autoCaller.release();
+        HRESULT rc = i_powerDown();
+        AssertComRC(rc);
+        autoCaller.add();
+        alock.acquire();
+    }
+    else
+    {
+        if (fPaused)
+            aLeftPaused = true;
+    }
 
-        /* create a thread to wait until the VM state is saved */
-        int vrc = RTThreadCreate(NULL, Console::i_saveStateThread, (void *)task.get(),
-                                 0, RTTHREADTYPE_MAIN_WORKER, 0, "VMSave");
-        if (RT_FAILURE(vrc))
-        {
-            rc = setError(E_FAIL, "Could not create VMSave thread (%Rrc)", vrc);
-            break;
-        }
+    LogFlowFuncLeave();
+    return S_OK;
+}
 
-        /* task is now owned by saveStateThread(), so release it */
-        task.release();
+/**
+ * Internal entry point for cancelling a VM save state.
+ *
+ * @note Locks this object for writing.
+ */
+HRESULT Console::i_cancelSaveState()
+{
+    LogFlowThisFuncEnter();
 
-        /* return the progress to the caller */
-        pProgress.queryInterfaceTo(aProgress);
-    } while (0);
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    if (FAILED(rc) && !fTaskCreationFailed)
-    {
-        /* preserve existing error info */
-        ErrorInfoKeeper eik;
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-        if (fBeganSavingState)
-        {
-            /*
-             * cancel the requested save state procedure.
-             * This will reset the machine state to the state it had right
-             * before calling mControl->BeginSavingState().
-             */
-            mControl->EndSavingState(eik.getResultCode(), eik.getText().raw());
-        }
+    /* Get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
-        if (lastMachineState == MachineState_Running)
-        {
-            /* restore the paused state if appropriate */
-            i_setMachineStateLocally(MachineState_Paused);
-            /* restore the running state if appropriate */
-            SafeVMPtr ptrVM(this);
-            if (ptrVM.isOk())
-            {
-                alock.release();
-                VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_STATE_RESTORED);
-                alock.acquire();
-            }
-        }
-        else
-            i_setMachineStateLocally(lastMachineState);
-    }
+    SSMR3Cancel(ptrVM.rawUVM());
 
-    LogFlowThisFunc(("rc=%Rhrc\n", rc));
-    LogFlowThisFuncLeave();
-    return rc;
+    LogFlowFuncLeave();
+    return S_OK;
 }
 
 /**
@@ -6795,16 +6487,100 @@ HRESULT Console::i_updateMachineState(MachineState_T aMachineState)
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     AssertReturn(   mMachineState == MachineState_Saving
+                 || mMachineState == MachineState_OnlineSnapshotting
                  || mMachineState == MachineState_LiveSnapshotting
-                 || mMachineState == MachineState_RestoringSnapshot
-                 || mMachineState == MachineState_DeletingSnapshot
                  || mMachineState == MachineState_DeletingSnapshotOnline
                  || mMachineState == MachineState_DeletingSnapshotPaused
+                 || aMachineState == MachineState_Saving
+                 || aMachineState == MachineState_OnlineSnapshotting
+                 || aMachineState == MachineState_LiveSnapshotting
+                 || aMachineState == MachineState_DeletingSnapshotOnline
+                 || aMachineState == MachineState_DeletingSnapshotPaused
                  , E_FAIL);
 
     return i_setMachineStateLocally(aMachineState);
 }
 
+/**
+ * Gets called by Session::COMGETTER(NominalState)()
+ * (IInternalSessionControl::getNominalState()).
+ *
+ * @note Locks this object for reading.
+ */
+HRESULT Console::i_getNominalState(MachineState_T &aNominalState)
+{
+    LogFlowThisFuncEnter();
+
+    AutoCaller autoCaller(this);
+    AssertComRCReturnRC(autoCaller.rc());
+
+    /* Get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    MachineState_T enmMachineState = MachineState_Null;
+    VMSTATE enmVMState = VMR3GetStateU(ptrVM.rawUVM());
+    switch (enmVMState)
+    {
+        case VMSTATE_CREATING:
+        case VMSTATE_CREATED:
+        case VMSTATE_POWERING_ON:
+            enmMachineState = MachineState_Starting;
+            break;
+        case VMSTATE_LOADING:
+            enmMachineState = MachineState_Restoring;
+            break;
+        case VMSTATE_RESUMING:
+        case VMSTATE_SUSPENDING:
+        case VMSTATE_SUSPENDING_LS:
+        case VMSTATE_SUSPENDING_EXT_LS:
+        case VMSTATE_SUSPENDED:
+        case VMSTATE_SUSPENDED_LS:
+        case VMSTATE_SUSPENDED_EXT_LS:
+            enmMachineState = MachineState_Paused;
+            break;
+        case VMSTATE_RUNNING:
+        case VMSTATE_RUNNING_LS:
+        case VMSTATE_RUNNING_FT:
+        case VMSTATE_RESETTING:
+        case VMSTATE_RESETTING_LS:
+        case VMSTATE_DEBUGGING:
+        case VMSTATE_DEBUGGING_LS:
+            enmMachineState = MachineState_Running;
+            break;
+        case VMSTATE_SAVING:
+            enmMachineState = MachineState_Saving;
+            break;
+        case VMSTATE_POWERING_OFF:
+        case VMSTATE_POWERING_OFF_LS:
+        case VMSTATE_DESTROYING:
+            enmMachineState = MachineState_Stopping;
+            break;
+        case VMSTATE_OFF:
+        case VMSTATE_OFF_LS:
+        case VMSTATE_FATAL_ERROR:
+        case VMSTATE_FATAL_ERROR_LS:
+        case VMSTATE_LOAD_FAILURE:
+        case VMSTATE_TERMINATED:
+            enmMachineState = MachineState_PoweredOff;
+            break;
+        case VMSTATE_GURU_MEDITATION:
+        case VMSTATE_GURU_MEDITATION_LS:
+            enmMachineState = MachineState_Stuck;
+            break;
+        default:
+            AssertMsgFailed(("%s\n", VMR3GetStateName(enmVMState)));
+            enmMachineState = MachineState_PoweredOff;
+    }
+    aNominalState = enmMachineState;
+
+    LogFlowFuncLeave();
+    return S_OK;
+}
+
 void Console::i_onMousePointerShapeChange(bool fVisible, bool fAlpha,
                                           uint32_t xHot, uint32_t yHot,
                                           uint32_t width, uint32_t height,
@@ -7210,7 +6986,6 @@ HRESULT Console::i_powerUp(IProgress **aProgress, bool aPaused)
 
     try
     {
-
         if (Global::IsOnlineOrTransient(mMachineState))
             throw setError(VBOX_E_INVALID_VM_STATE,
                 tr("The virtual machine is already running or busy (machine state: %s)"),
@@ -7323,8 +7098,8 @@ HRESULT Console::i_powerUp(IProgress **aProgress, bool aPaused)
             }
         }
 
-        /* Setup task object and thread to carry out the operaton
-         * Asycnhronously */
+        /* Setup task object and thread to carry out the operation
+         * asynchronously */
         std::auto_ptr<VMPowerUpTask> task(new VMPowerUpTask(this, pPowerupProgress));
         ComAssertComRCRetRC(task->rc());
 
@@ -7942,7 +7717,7 @@ HRESULT Console::i_powerDown(IProgress *aProgress /*= NULL*/)
  * @note Locks this object for writing.
  */
 HRESULT Console::i_setMachineState(MachineState_T aMachineState,
-                                 bool aUpdateServer /* = true */)
+                                   bool aUpdateServer /* = true */)
 {
     AutoCaller autoCaller(this);
     AssertComRCReturnRC(autoCaller.rc());
@@ -7955,6 +7730,7 @@ HRESULT Console::i_setMachineState(MachineState_T aMachineState,
     {
         LogThisFunc(("machineState=%s -> %s aUpdateServer=%RTbool\n",
                      Global::stringifyMachineState(mMachineState), Global::stringifyMachineState(aMachineState), aUpdateServer));
+        LogRel(("Console: machine state changed to %s\n", Global::stringifyMachineState(aMachineState)));
         mMachineState = aMachineState;
 
         /// @todo (dmik)
@@ -8565,7 +8341,7 @@ DECLCALLBACK(void) Console::i_vmstateChangeCallback(PUVM pUVM, VMSTATE enmState,
                     break;
 
                 case MachineState_LiveSnapshotting:
-                    that->i_setMachineState(MachineState_Saving);
+                    that->i_setMachineState(MachineState_OnlineSnapshotting);
                     break;
 
                 case MachineState_TeleportingPausedVM:
@@ -8574,11 +8350,10 @@ DECLCALLBACK(void) Console::i_vmstateChangeCallback(PUVM pUVM, VMSTATE enmState,
                 case MachineState_Stopping:
                 case MachineState_TeleportingIn:
                 case MachineState_FaultTolerantSyncing:
+                case MachineState_OnlineSnapshotting:
                     /* The worker thread handles the transition. */
                     break;
 
-                default:
-                    AssertMsgFailed(("%s\n", Global::stringifyMachineState(that->mMachineState)));
                 case MachineState_Running:
                     that->i_setMachineState(MachineState_Paused);
                     break;
@@ -8586,6 +8361,9 @@ DECLCALLBACK(void) Console::i_vmstateChangeCallback(PUVM pUVM, VMSTATE enmState,
                 case MachineState_Paused:
                     /* Nothing to do. */
                     break;
+
+                default:
+                    AssertMsgFailed(("%s\n", Global::stringifyMachineState(that->mMachineState)));
             }
             break;
         }
@@ -8603,7 +8381,7 @@ DECLCALLBACK(void) Console::i_vmstateChangeCallback(PUVM pUVM, VMSTATE enmState,
                     break;
 
                 case MachineState_LiveSnapshotting:
-                    that->i_setMachineState(MachineState_Saving);
+                    that->i_setMachineState(MachineState_OnlineSnapshotting);
                     break;
 
                 case MachineState_TeleportingPausedVM:
@@ -8747,9 +8525,9 @@ void Console::i_changeClipboardMode(ClipboardMode_T aClipboardMode)
 }
 
 /**
- * Changes the drag'n_drop mode.
+ * Changes the drag and drop mode.
  *
- * @param aDnDMode  new drag'n'drop mode.
+ * @param aDnDMode  new drag and drop mode.
  */
 int Console::i_changeDnDMode(DnDMode_T aDnDMode)
 {
@@ -8764,19 +8542,19 @@ int Console::i_changeDnDMode(DnDMode_T aDnDMode)
     {
         default:
         case DnDMode_Disabled:
-            LogRel(("Changed drag'n drop mode to: Off\n"));
+            LogRel(("Changed drag and drop mode to: Off\n"));
             parm.u.uint32 = VBOX_DRAG_AND_DROP_MODE_OFF;
             break;
         case DnDMode_GuestToHost:
-            LogRel(("Changed drag'n drop mode to: Guest to Host\n"));
+            LogRel(("Changed drag and drop mode to: Guest to Host\n"));
             parm.u.uint32 = VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST;
             break;
         case DnDMode_HostToGuest:
-            LogRel(("Changed drag'n drop mode to: Host to Guest\n"));
+            LogRel(("Changed drag and drop mode to: Host to Guest\n"));
             parm.u.uint32 = VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST;
             break;
         case DnDMode_Bidirectional:
-            LogRel(("Changed drag'n drop mode to: Bidirectional\n"));
+            LogRel(("Changed drag and drop mode to: Bidirectional\n"));
             parm.u.uint32 = VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL;
             break;
     }
@@ -9663,8 +9441,7 @@ DECLCALLBACK(int) Console::i_powerUpThread(RTTHREAD Thread, void *pvUser)
     {
         // Create the VMM device object, which starts the HGCM thread; do this only
         // once for the console, for the pathological case that the same console
-        // object is used to power up a VM twice. VirtualBox 4.0: we now do that
-        // here instead of the Console constructor (see Console::init())
+        // object is used to power up a VM twice.
         if (!pConsole->m_pVMMDev)
         {
             pConsole->m_pVMMDev = new VMMDev(pConsole);
@@ -10152,410 +9929,6 @@ DECLCALLBACK(int) Console::i_reconfigureMediumAttachment(Console *pThis,
 }
 
 /**
- * Progress cancelation callback employed by Console::fntTakeSnapshotWorker.
- */
-static void takesnapshotProgressCancelCallback(void *pvUser)
-{
-    PUVM pUVM = (PUVM)pvUser;
-    SSMR3Cancel(pUVM);
-}
-
-/**
- * Worker thread created by Console::TakeSnapshot.
- * @param Thread The current thread (ignored).
- * @param pvUser The task.
- * @return VINF_SUCCESS (ignored).
- */
-/*static*/
-DECLCALLBACK(int) Console::i_fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
-{
-    VMTakeSnapshotTask *pTask = (VMTakeSnapshotTask*)pvUser;
-
-    // taking a snapshot consists of the following:
-
-    // 1) creating a diff image for each virtual hard disk, into which write operations go after
-    //    the snapshot has been created (done in VBoxSVC, in SessionMachine::BeginTakingSnapshot)
-    // 2) creating a Snapshot object with the state of the machine (hardware + storage,
-    //    done in VBoxSVC, also in SessionMachine::BeginTakingSnapshot)
-    // 3) saving the state of the virtual machine (here, in the VM process, if the machine is online)
-
-    Console    *that                 = pTask->mConsole;
-    bool        fBeganTakingSnapshot = false;
-    bool        fSuspenededBySave    = false;
-
-    AutoCaller autoCaller(that);
-    if (FAILED(autoCaller.rc()))
-    {
-        that->mptrCancelableProgress.setNull();
-        return autoCaller.rc();
-    }
-
-    AutoWriteLock alock(that COMMA_LOCKVAL_SRC_POS);
-
-    HRESULT rc = S_OK;
-
-    try
-    {
-        /* STEP 1 + 2:
-         * request creating the diff images on the server and create the snapshot object
-         * (this will set the machine state to Saving on the server to block
-         * others from accessing this machine)
-         */
-        rc = that->mControl->BeginTakingSnapshot(that,
-                                                 pTask->bstrName.raw(),
-                                                 pTask->bstrDescription.raw(),
-                                                 pTask->mProgress,
-                                                 pTask->fTakingSnapshotOnline,
-                                                 pTask->bstrSavedStateFile.asOutParam());
-        if (FAILED(rc))
-            throw rc;
-
-        fBeganTakingSnapshot = true;
-
-        /* Check sanity: for offline snapshots there must not be a saved state
-         * file name. All other combinations are valid (even though online
-         * snapshots without saved state file seems inconsistent - there are
-         * some exotic use cases, which need to be explicitly enabled, see the
-         * code of SessionMachine::BeginTakingSnapshot. */
-        if (   !pTask->fTakingSnapshotOnline
-            && !pTask->bstrSavedStateFile.isEmpty())
-            throw i_setErrorStatic(E_FAIL, "Invalid state of saved state file");
-
-        /* sync the state with the server */
-        if (pTask->lastMachineState == MachineState_Running)
-            that->i_setMachineStateLocally(MachineState_LiveSnapshotting);
-        else
-            that->i_setMachineStateLocally(MachineState_Saving);
-
-        // STEP 3: save the VM state (if online)
-        if (pTask->fTakingSnapshotOnline)
-        {
-            int vrc;
-            SafeVMPtr ptrVM(that);
-            if (!ptrVM.isOk())
-                throw ptrVM.rc();
-
-            pTask->mProgress->SetNextOperation(Bstr(tr("Saving the machine state")).raw(),
-                                               pTask->ulMemSize);       // operation weight, same as computed
-                                                                        // when setting up progress object
-            if (!pTask->bstrSavedStateFile.isEmpty())
-            {
-                Utf8Str strSavedStateFile(pTask->bstrSavedStateFile);
-
-                pTask->mProgress->i_setCancelCallback(takesnapshotProgressCancelCallback, ptrVM.rawUVM());
-
-                alock.release();
-                LogFlowFunc(("VMR3Save...\n"));
-                vrc = VMR3Save(ptrVM.rawUVM(),
-                               strSavedStateFile.c_str(),
-                               true /*fContinueAfterwards*/,
-                               Console::i_stateProgressCallback,
-                               static_cast<IProgress *>(pTask->mProgress),
-                               &fSuspenededBySave);
-                alock.acquire();
-                if (RT_FAILURE(vrc))
-                    throw i_setErrorStatic(E_FAIL,
-                                         tr("Failed to save the machine state to '%s' (%Rrc)"),
-                                         strSavedStateFile.c_str(), vrc);
-
-                pTask->mProgress->i_setCancelCallback(NULL, NULL);
-            }
-            else
-                LogRel(("Console: skipped saving state as part of online snapshot\n"));
-
-            if (!pTask->mProgress->i_notifyPointOfNoReturn())
-                throw i_setErrorStatic(E_FAIL, tr("Canceled"));
-            that->mptrCancelableProgress.setNull();
-
-            // STEP 4: reattach hard disks
-            LogFlowFunc(("Reattaching new differencing hard disks...\n"));
-
-            pTask->mProgress->SetNextOperation(Bstr(tr("Reconfiguring medium attachments")).raw(),
-                                               1);       // operation weight, same as computed when setting up progress object
-
-            com::SafeIfaceArray<IMediumAttachment> atts;
-            rc = that->mMachine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(atts));
-            if (FAILED(rc))
-                throw rc;
-
-            for (size_t i = 0;
-                i < atts.size();
-                ++i)
-            {
-                ComPtr<IStorageController> pStorageController;
-                Bstr controllerName;
-                ULONG lInstance;
-                StorageControllerType_T enmController;
-                StorageBus_T enmBus;
-                BOOL fUseHostIOCache;
-
-                /*
-                * We can't pass a storage controller object directly
-                * (g++ complains about not being able to pass non POD types through '...')
-                * so we have to query needed values here and pass them.
-                */
-                rc = atts[i]->COMGETTER(Controller)(controllerName.asOutParam());
-                if (FAILED(rc))
-                    throw rc;
-
-                rc = that->mMachine->GetStorageControllerByName(controllerName.raw(),
-                                                                pStorageController.asOutParam());
-                if (FAILED(rc))
-                    throw rc;
-
-                rc = pStorageController->COMGETTER(ControllerType)(&enmController);
-                if (FAILED(rc))
-                    throw rc;
-                rc = pStorageController->COMGETTER(Instance)(&lInstance);
-                if (FAILED(rc))
-                    throw rc;
-                rc = pStorageController->COMGETTER(Bus)(&enmBus);
-                if (FAILED(rc))
-                    throw rc;
-                rc = pStorageController->COMGETTER(UseHostIOCache)(&fUseHostIOCache);
-                if (FAILED(rc))
-                    throw rc;
-
-                const char *pcszDevice = Console::i_convertControllerTypeToDev(enmController);
-
-                BOOL fBuiltinIOCache;
-                rc = that->mMachine->COMGETTER(IOCacheEnabled)(&fBuiltinIOCache);
-                if (FAILED(rc))
-                    throw rc;
-
-                alock.release();
-                vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY,
-                                       (PFNRT)i_reconfigureMediumAttachment, 13,
-                                       that, ptrVM.rawUVM(), pcszDevice, lInstance, enmBus, fUseHostIOCache,
-                                       fBuiltinIOCache, false /* fSetupMerge */, 0 /* uMergeSource */,
-                                       0 /* uMergeTarget */, atts[i], that->mMachineState, &rc);
-                alock.acquire();
-                if (RT_FAILURE(vrc))
-                    throw i_setErrorStatic(E_FAIL, Console::tr("%Rrc"), vrc);
-                if (FAILED(rc))
-                    throw rc;
-            }
-        }
-
-        /*
-         * finalize the requested snapshot object.
-         * This will reset the machine state to the state it had right
-         * before calling mControl->BeginTakingSnapshot().
-         */
-        rc = that->mControl->EndTakingSnapshot(TRUE /*aSuccess*/);
-        // do not throw rc here because we can't call EndTakingSnapshot() twice
-        LogFlowFunc(("EndTakingSnapshot -> %Rhrc [mMachineState=%s]\n", rc, Global::stringifyMachineState(that->mMachineState)));
-    }
-    catch (HRESULT rcThrown)
-    {
-        /* preserve existing error info */
-        ErrorInfoKeeper eik;
-
-        if (fBeganTakingSnapshot)
-            that->mControl->EndTakingSnapshot(FALSE /*aSuccess*/);
-
-        rc = rcThrown;
-        LogFunc(("Caught %Rhrc [mMachineState=%s]\n", rc, Global::stringifyMachineState(that->mMachineState)));
-    }
-    Assert(alock.isWriteLockOnCurrentThread());
-
-    if (FAILED(rc)) /* Must come before calling setMachineState. */
-        pTask->mProgress->i_notifyComplete(rc);
-
-    /*
-     * Fix up the machine state.
-     *
-     * For live snapshots we do all the work, for the two other variations we
-     * just update the local copy.
-     */
-    MachineState_T enmMachineState;
-    that->mMachine->COMGETTER(State)(&enmMachineState);
-    if (   that->mMachineState == MachineState_LiveSnapshotting
-        || that->mMachineState == MachineState_Saving)
-    {
-
-        if (!pTask->fTakingSnapshotOnline)
-            that->i_setMachineStateLocally(pTask->lastMachineState);
-        else if (SUCCEEDED(rc))
-        {
-            Assert(   pTask->lastMachineState == MachineState_Running
-                   || pTask->lastMachineState == MachineState_Paused);
-            Assert(that->mMachineState == MachineState_Saving);
-            if (pTask->lastMachineState == MachineState_Running)
-            {
-                LogFlowFunc(("VMR3Resume...\n"));
-                SafeVMPtr ptrVM(that);
-                alock.release();
-                int vrc = VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_STATE_SAVED);
-                alock.acquire();
-                if (RT_FAILURE(vrc))
-                {
-                    rc = i_setErrorStatic(VBOX_E_VM_ERROR, tr("Could not resume the machine execution (%Rrc)"), vrc);
-                    pTask->mProgress->i_notifyComplete(rc);
-                    if (that->mMachineState == MachineState_Saving)
-                        that->i_setMachineStateLocally(MachineState_Paused);
-                }
-            }
-            else
-                that->i_setMachineStateLocally(MachineState_Paused);
-        }
-        else
-        {
-            /** @todo this could probably be made more generic and reused elsewhere. */
-            /* paranoid cleanup on for a failed online snapshot. */
-            VMSTATE enmVMState = VMR3GetStateU(that->mpUVM);
-            switch (enmVMState)
-            {
-                case VMSTATE_RUNNING:
-                case VMSTATE_RUNNING_LS:
-                case VMSTATE_DEBUGGING:
-                case VMSTATE_DEBUGGING_LS:
-                case VMSTATE_POWERING_OFF:
-                case VMSTATE_POWERING_OFF_LS:
-                case VMSTATE_RESETTING:
-                case VMSTATE_RESETTING_LS:
-                    Assert(!fSuspenededBySave);
-                    that->i_setMachineState(MachineState_Running);
-                    break;
-
-                case VMSTATE_GURU_MEDITATION:
-                case VMSTATE_GURU_MEDITATION_LS:
-                    that->i_setMachineState(MachineState_Stuck);
-                    break;
-
-                case VMSTATE_FATAL_ERROR:
-                case VMSTATE_FATAL_ERROR_LS:
-                    if (pTask->lastMachineState == MachineState_Paused)
-                        that->i_setMachineStateLocally(pTask->lastMachineState);
-                    else
-                        that->i_setMachineState(MachineState_Paused);
-                    break;
-
-                default:
-                    AssertMsgFailed(("%s\n", VMR3GetStateName(enmVMState)));
-                case VMSTATE_SUSPENDED:
-                case VMSTATE_SUSPENDED_LS:
-                case VMSTATE_SUSPENDING:
-                case VMSTATE_SUSPENDING_LS:
-                case VMSTATE_SUSPENDING_EXT_LS:
-                    if (fSuspenededBySave)
-                    {
-                        Assert(pTask->lastMachineState == MachineState_Running);
-                        LogFlowFunc(("VMR3Resume (on failure)...\n"));
-                        SafeVMPtr ptrVM(that);
-                        alock.release();
-                        int vrc = VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_STATE_SAVED); AssertLogRelRC(vrc);
-                        alock.acquire();
-                        if (RT_FAILURE(vrc))
-                            that->i_setMachineState(MachineState_Paused);
-                    }
-                    else if (pTask->lastMachineState == MachineState_Paused)
-                        that->i_setMachineStateLocally(pTask->lastMachineState);
-                    else
-                        that->i_setMachineState(MachineState_Paused);
-                    break;
-            }
-
-        }
-    }
-    /*else: somebody else has change the state... Leave it. */
-
-    /* check the remote state to see that we got it right. */
-    that->mMachine->COMGETTER(State)(&enmMachineState);
-    AssertLogRelMsg(that->mMachineState == enmMachineState,
-                    ("mMachineState=%s enmMachineState=%s\n", Global::stringifyMachineState(that->mMachineState),
-                     Global::stringifyMachineState(enmMachineState) ));
-
-
-    if (SUCCEEDED(rc)) /* The failure cases are handled above. */
-        pTask->mProgress->i_notifyComplete(rc);
-
-    delete pTask;
-
-    LogFlowFuncLeave();
-    return VINF_SUCCESS;
-}
-
-/**
- * Thread for executing the saved state operation.
- *
- * @param   Thread      The thread handle.
- * @param   pvUser      Pointer to a VMSaveTask structure.
- * @return  VINF_SUCCESS (ignored).
- *
- * @note Locks the Console object for writing.
- */
-/*static*/
-DECLCALLBACK(int) Console::i_saveStateThread(RTTHREAD Thread, void *pvUser)
-{
-    LogFlowFuncEnter();
-
-    std::auto_ptr<VMSaveTask> task(static_cast<VMSaveTask*>(pvUser));
-    AssertReturn(task.get(), VERR_INVALID_PARAMETER);
-
-    Assert(task->mSavedStateFile.length());
-    Assert(task->mProgress.isNull());
-    Assert(!task->mServerProgress.isNull());
-
-    const ComObjPtr<Console> &that = task->mConsole;
-    Utf8Str errMsg;
-    HRESULT rc = S_OK;
-
-    LogFlowFunc(("Saving the state to '%s'...\n", task->mSavedStateFile.c_str()));
-
-    bool fSuspenededBySave;
-    int vrc = VMR3Save(task->mpUVM,
-                       task->mSavedStateFile.c_str(),
-                       false, /*fContinueAfterwards*/
-                       Console::i_stateProgressCallback,
-                       static_cast<IProgress *>(task->mServerProgress),
-                       &fSuspenededBySave);
-    if (RT_FAILURE(vrc))
-    {
-        errMsg = Utf8StrFmt(Console::tr("Failed to save the machine state to '%s' (%Rrc)"),
-                            task->mSavedStateFile.c_str(), vrc);
-        rc = E_FAIL;
-    }
-    Assert(!fSuspenededBySave);
-
-    /* lock the console once we're going to access it */
-    AutoWriteLock thatLock(that COMMA_LOCKVAL_SRC_POS);
-
-    /* synchronize the state with the server */
-    if (SUCCEEDED(rc))
-    {
-        /*
-         * The machine has been successfully saved, so power it down
-         * (vmstateChangeCallback() will set state to Saved on success).
-         * Note: we release the task's VM caller, otherwise it will
-         * deadlock.
-         */
-        task->releaseVMCaller();
-        thatLock.release();
-        rc = that->i_powerDown();
-        thatLock.acquire();
-    }
-
-    /*
-     * If we failed, reset the local machine state.
-     */
-    if (FAILED(rc))
-        that->i_setMachineStateLocally(task->mMachineStateBefore);
-
-    /*
-     * Finalize the requested save state procedure. In case of failure it will
-     * reset the machine state to the state it had right before calling
-     * mControl->BeginSavingState(). This must be the last thing because it
-     * will set the progress to completed, and that means that the frontend
-     * can immediately uninit the associated console object.
-     */
-    that->mControl->EndSavingState(rc, Bstr(errMsg).raw());
-
-    LogFlowFuncLeave();
-    return VINF_SUCCESS;
-}
-
-/**
  * Thread for powering down the Console.
  *
  * @param   Thread      The thread handle.
@@ -10610,9 +9983,12 @@ Console::i_vmm2User_SaveState(PCVMM2USERMETHODS pThis, PUVM pUVM)
 
     /*
      * For now, just call SaveState.  We should probably try notify the GUI so
-     * it can pop up a progress object and stuff.
+     * it can pop up a progress object and stuff. The progress object created
+     * by the call isn't returned to anyone and thus gets updated without
+     * anyone noticing it.
      */
-    HRESULT hrc = pConsole->SaveState(NULL);
+    ComPtr<IProgress> pProgress;
+    HRESULT hrc = pConsole->mMachine->SaveState(pProgress.asOutParam());
     return SUCCEEDED(hrc) ? VINF_SUCCESS : Global::vboxStatusCodeFromCOM(hrc);
 }
 
@@ -10681,18 +10057,16 @@ Console::i_pdmIfSecKey_KeyRetain(PPDMISECKEY pInterface, const char *pszId, cons
     Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
 
     AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
-    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
-    if (it != pConsole->m_mapSecretKeys.end())
-    {
-        SecretKey *pKey = (*it).second;
+    SecretKey *pKey = NULL;
 
-        ASMAtomicIncU32(&pKey->m_cRefs);
-        *ppbKey = pKey->m_pbKey;
-        *pcbKey = pKey->m_cbKey;
-        return VINF_SUCCESS;
+    int rc = pConsole->m_pKeyStore->retainSecretKey(Utf8Str(pszId), &pKey);
+    if (RT_SUCCESS(rc))
+    {
+        *ppbKey = (const uint8_t *)pKey->getKeyBuffer();
+        *pcbKey = pKey->getKeySize();
     }
 
-    return VERR_NOT_FOUND;
+    return rc;
 }
 
 /**
@@ -10704,15 +10078,7 @@ Console::i_pdmIfSecKey_KeyRelease(PPDMISECKEY pInterface, const char *pszId)
     Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
 
     AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
-    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
-    if (it != pConsole->m_mapSecretKeys.end())
-    {
-        SecretKey *pKey = (*it).second;
-        ASMAtomicDecU32(&pKey->m_cRefs);
-        return VINF_SUCCESS;
-    }
-
-    return VERR_NOT_FOUND;
+    return pConsole->m_pKeyStore->releaseSecretKey(Utf8Str(pszId));
 }
 
 /**
@@ -10724,22 +10090,13 @@ Console::i_pdmIfSecKey_PasswordRetain(PPDMISECKEY pInterface, const char *pszId,
     Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
 
     AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
-    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
-    if (it != pConsole->m_mapSecretKeys.end())
-    {
-        SecretKey *pKey = (*it).second;
+    SecretKey *pKey = NULL;
 
-        uint32_t cRefs = ASMAtomicIncU32(&pKey->m_cRefs);
-        if (cRefs == 1)
-        {
-            int rc = RTMemSaferUnscramble(pKey->m_pbKey, pKey->m_cbKey);
-            AssertRC(rc);
-        }
-        *ppszPassword = (const char *)pKey->m_pbKey;
-        return VINF_SUCCESS;
-    }
+    int rc = pConsole->m_pKeyStore->retainSecretKey(Utf8Str(pszId), &pKey);
+    if (RT_SUCCESS(rc))
+        *ppszPassword = (const char *)pKey->getKeyBuffer();
 
-    return VERR_NOT_FOUND;
+    return rc;
 }
 
 /**
@@ -10751,20 +10108,7 @@ Console::i_pdmIfSecKey_PasswordRelease(PPDMISECKEY pInterface, const char *pszId
     Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
 
     AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
-    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
-    if (it != pConsole->m_mapSecretKeys.end())
-    {
-        SecretKey *pKey = (*it).second;
-        uint32_t cRefs = ASMAtomicDecU32(&pKey->m_cRefs);
-        if (!cRefs)
-        {
-            int rc = RTMemSaferScramble(pKey->m_pbKey, pKey->m_cbKey);
-            AssertRC(rc);
-        }
-        return VINF_SUCCESS;
-    }
-
-    return VERR_NOT_FOUND;
+    return pConsole->m_pKeyStore->releaseSecretKey(Utf8Str(pszId));
 }
 
 /**
diff --git a/src/VBox/Main/src-client/ConsoleImpl2.cpp b/src/VBox/Main/src-client/ConsoleImpl2.cpp
index 009626c..6f68a1d 100644
--- a/src/VBox/Main/src-client/ConsoleImpl2.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl2.cpp
@@ -9,7 +9,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -1184,10 +1184,7 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
 
         /*
          * Paravirt. provider.
-         * Currently only enabled for HM VMs as raw-mode GIM still needs work.
          */
-        if (!fHMEnabled)
-            paravirtProvider = ParavirtProvider_None;
         PCFGMNODE pParavirtNode;
         InsertConfigNode(pRoot, "GIM", &pParavirtNode);
         const char *pcszParavirtProvider;
@@ -2530,6 +2527,15 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
                     InsertConfigNode(pLunL0,    "Config", &pLunL1);
                     InsertConfigString(pLunL1,  "DevicePath", bstr);
                 }
+                else if (eHostMode == PortMode_TCP)
+                {
+                    InsertConfigString(pLunL0,  "Driver", "Char");
+                    InsertConfigNode(pLunL0,    "AttachedDriver", &pLunL1);
+                    InsertConfigString(pLunL1,  "Driver", "TCP");
+                    InsertConfigNode(pLunL1,    "Config", &pLunL2);
+                    InsertConfigString(pLunL2,  "Location", bstr);
+                    InsertConfigInteger(pLunL2, "IsServer", fServer);
+                }
                 else if (eHostMode == PortMode_RawFile)
                 {
                     InsertConfigString(pLunL0,  "Driver", "Char");
@@ -2719,7 +2725,7 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
                     LogRel(("Audio: WARNING: Solaris Audio is deprecated, please switch to OSS!\n"));
                     LogRel(("Audio: Automatically setting host audio backend to OSS\n"));
                     /* Manually set backend to OSS for now. */
-                    InsertConfigString(pLunL1, "Driver", "OSSAudio"); 
+                    InsertConfigString(pLunL1, "Driver", "OSSAudio");
 # else
                     InsertConfigString(pCfg, "AudioDriver", "solaudio");
 # endif
@@ -2851,7 +2857,7 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
 
 #ifdef VBOX_WITH_DRAG_AND_DROP
         /*
-         * Drag'n Drop.
+         * Drag and Drop.
          */
         {
             DnDMode_T enmMode = DnDMode_Disabled;
@@ -2861,7 +2867,7 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
             rc = pVMMDev->hgcmLoadService("VBoxDragAndDropSvc", "VBoxDragAndDropSvc");
             if (RT_FAILURE(rc))
             {
-                LogRel(("Drag'n drop service is not available, rc=%Rrc\n", rc));
+                LogRel(("Drag and drop service is not available, rc=%Rrc\n", rc));
                 /* That is not a fatal failure. */
                 rc = VINF_SUCCESS;
             }
@@ -2875,7 +2881,7 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
                     Log(("Cannot register VBoxDragAndDropSvc extension, rc=%Rrc\n", rc));
                 else
                 {
-                    LogRel(("Drag'n drop service loaded\n"));
+                    LogRel(("Drag and drop service loaded\n"));
                     rc = i_changeDnDMode(enmMode);
                 }
             }
diff --git a/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp b/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
index 45434b3..988ddd4 100644
--- a/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
+++ b/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2010-2014 Oracle Corporation
+ * Copyright (C) 2010-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -996,7 +996,7 @@ HRESULT Console::teleport(const com::Utf8Str &aHostname, ULONG aTcpport, const c
         if (SUCCEEDED(hrc))
         {
             ptrProgress.queryInterfaceTo(aProgress.asOutParam());
-            mptrCancelableProgress = ptrProgress;
+            mptrCancelableProgress = aProgress;
         }
         else
             ptrProgress->Cancel();
diff --git a/src/VBox/Main/src-client/DisplayImpl.cpp b/src/VBox/Main/src-client/DisplayImpl.cpp
index d96a94b..3ced72b 100644
--- a/src/VBox/Main/src-client/DisplayImpl.cpp
+++ b/src/VBox/Main/src-client/DisplayImpl.cpp
@@ -1601,7 +1601,7 @@ HRESULT Display::getScreenResolution(ULONG aScreenId, ULONG *aWidth, ULONG *aHei
 }
 
 
-HRESULT Display::attachFramebuffer(ULONG aScreenId, const ComPtr<IFramebuffer> &aFramebuffer)
+HRESULT Display::attachFramebuffer(ULONG aScreenId, const ComPtr<IFramebuffer> &aFramebuffer, com::Guid &aId)
 {
     LogRelFlowFunc(("aScreenId = %d\n", aScreenId));
 
@@ -1617,6 +1617,8 @@ HRESULT Display::attachFramebuffer(ULONG aScreenId, const ComPtr<IFramebuffer> &
                         aScreenId);
 
     pFBInfo->pFramebuffer = aFramebuffer;
+    pFBInfo->framebufferId.create();
+    aId = pFBInfo->framebufferId;
 
     SafeArray<FramebufferCapabilities_T> caps;
     pFBInfo->pFramebuffer->COMGETTER(Capabilities)(ComSafeArrayAsOutParam(caps));
@@ -1662,13 +1664,13 @@ HRESULT Display::attachFramebuffer(ULONG aScreenId, const ComPtr<IFramebuffer> &
                            3, this, aScreenId, false);
     }
 
-    LogRelFlowFunc(("Attached to %d\n", aScreenId));
+    LogRelFlowFunc(("Attached to %d %RTuuid\n", aScreenId, aId.raw()));
     return S_OK;
 }
 
-HRESULT Display::detachFramebuffer(ULONG aScreenId)
+HRESULT Display::detachFramebuffer(ULONG aScreenId, const com::Guid &aId)
 {
-    LogRelFlowFunc(("aScreenId = %d\n", aScreenId));
+    LogRelFlowFunc(("aScreenId = %d %RTuuid\n", aScreenId, aId.raw()));
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -1678,7 +1680,14 @@ HRESULT Display::detachFramebuffer(ULONG aScreenId)
 
     DISPLAYFBINFO *pFBInfo = &maFramebuffers[aScreenId];
 
+    if (pFBInfo->framebufferId != aId)
+    {
+        LogRelFlowFunc(("Invalid framebuffer aScreenId = %d, attached %p\n", aScreenId, pFBInfo->framebufferId.raw()));
+        return setError(E_FAIL, tr("DetachFramebuffer: Invalid framebuffer object"));
+    }
+
     pFBInfo->pFramebuffer.setNull();
+    pFBInfo->framebufferId.clear();
 
     alock.release();
 
diff --git a/src/VBox/Main/src-client/DrvAudioVRDE.cpp b/src/VBox/Main/src-client/DrvAudioVRDE.cpp
index 5f51fe4..3471773 100644
--- a/src/VBox/Main/src-client/DrvAudioVRDE.cpp
+++ b/src/VBox/Main/src-client/DrvAudioVRDE.cpp
@@ -411,6 +411,9 @@ int AudioVRDE::onVRDEControl(bool fEnable, uint32_t uFlags)
 {
     LogFlowThisFunc(("fEnable=%RTbool, uFlags=0x%x\n", fEnable, uFlags));
 
+    if (mpDrv == NULL)
+        return VERR_INVALID_STATE;
+
     mpDrv->fEnabled = fEnable;
 
     return VINF_SUCCESS; /* Never veto. */
diff --git a/src/VBox/Main/src-client/GuestDnDPrivate.cpp b/src/VBox/Main/src-client/GuestDnDPrivate.cpp
index 4eb1f87..a459096 100644
--- a/src/VBox/Main/src-client/GuestDnDPrivate.cpp
+++ b/src/VBox/Main/src-client/GuestDnDPrivate.cpp
@@ -224,7 +224,7 @@ Utf8Str GuestDnDResponse::errorToString(const ComObjPtr<Guest>& pGuest, int gues
             /* Should not happen due to file locking on the guest, but anyway ... */
             strError += Utf8StrFmt(pGuest->tr("One or more guest files or directories selected for transferring to the host were not"
                                               "found on the guest anymore. This can be the case if the guest files were moved and/or"
-                                              "altered while the drag'n drop operation was in progress."));
+                                              "altered while the drag and drop operation was in progress."));
             break;
 
         case VERR_SHARING_VIOLATION:
@@ -234,7 +234,7 @@ Utf8Str GuestDnDResponse::errorToString(const ComObjPtr<Guest>& pGuest, int gues
             break;
 
         default:
-            strError += Utf8StrFmt("Drag'n drop guest error (%Rrc)", guestRc);
+            strError += Utf8StrFmt("Drag and drop guest error (%Rrc)", guestRc);
             break;
     }
 
@@ -281,7 +281,7 @@ HRESULT GuestDnDResponse::resetProgress(const ComObjPtr<Guest>& pParent)
     {
         rc = m_progress->init(static_cast<IGuest*>(pParent),
                               Bstr(pParent->tr("Dropping data")).raw(),
-                              TRUE);
+                              FALSE /* fCancelable */);
     }
     return rc;
 }
diff --git a/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp b/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
index d16a8d6..8b23fbe 100644
--- a/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
+++ b/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
@@ -1,6 +1,6 @@
 /* $Id: GuestDnDSourceImpl.cpp $ */
 /** @file
- * VBox Console COM Class implementation - Guest drag'n drop source.
+ * VBox Console COM Class implementation - Guest drag and drop source.
  */
 
 /*
@@ -260,7 +260,7 @@ HRESULT GuestDnDSource::drop(const com::Utf8Str &aFormat,
             LogFlowFunc(("rc=%Rrc, szDropDir=%s\n", rc, szDropDir));
             if (RT_FAILURE(rc))
                 return setError(VBOX_E_IPRT_ERROR,
-                                tr("Unable to create the temporary drag'n drop directory \"%s\" (%Rrc)\n"),
+                                tr("Unable to create the temporary drag and drop directory \"%s\" (%Rrc)\n"),
                                 szDropDir, rc);
 
             pResp->setDropDir(szDropDir);
diff --git a/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp b/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
index c475efe..7963b6c 100644
--- a/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
+++ b/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
@@ -431,9 +431,8 @@ HRESULT GuestDnDTarget::sendData(ULONG aScreenId,
                                           i, paParms);
         if (RT_SUCCESS(rc))
         {
-            /* Query the progress object to the caller. */
-            if (aProgress)
-                pResp->queryProgressTo(aProgress.asOutParam());
+            hr = pResp->queryProgressTo(aProgress.asOutParam());
+            ComAssertComRC(hr);
         }
     }
 
diff --git a/src/VBox/Main/src-client/GuestImpl.cpp b/src/VBox/Main/src-client/GuestImpl.cpp
index 9478e12..d783984 100644
--- a/src/VBox/Main/src-client/GuestImpl.cpp
+++ b/src/VBox/Main/src-client/GuestImpl.cpp
@@ -130,7 +130,7 @@ HRESULT Guest::init(Console *aParent)
                 hr = mDnDTarget->init(this /* pGuest */);
         }
 
-        LogFlowFunc(("Drag'n drop initializied with hr=%Rhrc\n", hr));
+        LogFlowFunc(("Drag and drop initializied with hr=%Rhrc\n", hr));
     }
     catch (std::bad_alloc &)
     {
diff --git a/src/VBox/Main/src-client/SessionImpl.cpp b/src/VBox/Main/src-client/SessionImpl.cpp
index 68e6ba6..f2a3497 100644
--- a/src/VBox/Main/src-client/SessionImpl.cpp
+++ b/src/VBox/Main/src-client/SessionImpl.cpp
@@ -122,7 +122,7 @@ void Session::uninit()
         Assert(mState == SessionState_Locked ||
                mState == SessionState_Spawning);
 
-        HRESULT rc = unlockMachine(true /* aFinalRelease */, false /* aFromServer */);
+        HRESULT rc = i_unlockMachine(true /* aFinalRelease */, false /* aFromServer */);
         AssertComRC(rc);
     }
 
@@ -166,16 +166,15 @@ HRESULT Session::getMachine(ComPtr<IMachine> &aMachine)
         rc = mRemoteMachine.queryInterfaceTo(aMachine.asOutParam());
     if (FAILED(rc))
     {
-        /** @todo VBox 3.3: replace E_FAIL with rc here. */
 #ifndef VBOX_COM_INPROC_API_CLIENT
         if (mConsole)
-            setError(E_FAIL, tr("Failed to query the session machine (%Rhrc)"), rc);
+            setError(rc, tr("Failed to query the session machine"));
         else
 #endif
         if (FAILED_DEAD_INTERFACE(rc))
-            setError(E_FAIL, tr("Peer process crashed"));
+            setError(rc, tr("Peer process crashed"));
         else
-            setError(E_FAIL, tr("Failed to query the remote session machine (%Rhrc)"), rc);
+            setError(rc, tr("Failed to query the remote session machine"));
     }
 
     return rc;
@@ -197,16 +196,15 @@ HRESULT Session::getConsole(ComPtr<IConsole> &aConsole)
 
     if (FAILED(rc))
     {
-        /** @todo VBox 3.3: replace E_FAIL with rc here. */
 #ifndef VBOX_COM_INPROC_API_CLIENT
         if (mConsole)
-            setError(E_FAIL, tr("Failed to query the console (%Rhrc)"), rc);
+            setError(rc, tr("Failed to query the console"));
         else
 #endif
         if (FAILED_DEAD_INTERFACE(rc))
-            setError(E_FAIL, tr("Peer process crashed"));
+            setError(rc, tr("Peer process crashed"));
         else
-            setError(E_FAIL, tr("Failed to query the remote console (%Rhrc)"), rc);
+            setError(rc, tr("Failed to query the remote console"));
     }
 
     return rc;
@@ -223,7 +221,7 @@ HRESULT Session::unlockMachine()
 
     CHECK_OPEN();
 
-    return unlockMachine(false /* aFinalRelease */, false /* aFromServer */);
+    return i_unlockMachine(false /* aFinalRelease */, false /* aFromServer */);
 }
 
 // IInternalSessionControl methods
@@ -266,6 +264,21 @@ HRESULT Session::getRemoteConsole(ComPtr<IConsole> &aConsole)
 #endif /* VBOX_COM_INPROC_API_CLIENT */
 }
 
+HRESULT Session::getNominalState(MachineState_T *aNominalState)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
+    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
+#ifndef VBOX_COM_INPROC_API_CLIENT
+    AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
+
+    return mConsole->i_getNominalState(*aNominalState);
+#else
+    AssertFailed();
+    return E_NOTIMPL;
+#endif
+}
+
 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
 HRESULT Session::assignMachine(const ComPtr<IMachine> &aMachine,
                                LockType_T aLockType,
@@ -299,14 +312,21 @@ HRESULT Session::assignMachine(const ComPtr<IMachine> &aMachine,
     mControl = aMachine;
     AssertReturn(!!mControl, E_FAIL);
 
+    HRESULT rc = S_OK;
 #ifndef VBOX_COM_INPROC_API_CLIENT
-    HRESULT rc = mConsole.createObject();
-    AssertComRCReturn(rc, rc);
+    if (aLockType == LockType_VM)
+    {
+        /* This is what is special about VM processes: they have a Console
+         * object which is the root of all VM related activity. */
+        rc = mConsole.createObject();
+        AssertComRCReturn(rc, rc);
 
-    rc = mConsole->init(aMachine, mControl, aLockType);
-    AssertComRCReturn(rc, rc);
+        rc = mConsole->init(aMachine, mControl, aLockType);
+        AssertComRCReturn(rc, rc);
+    }
+    else
+        mRemoteMachine = aMachine;
 #else
-    HRESULT rc = S_OK;
     mRemoteMachine = aMachine;
 #endif
 
@@ -368,7 +388,7 @@ HRESULT Session::assignRemoteMachine(const ComPtr<IMachine> &aMachine,
                                      const ComPtr<IConsole> &aConsole)
 
 {
-    AssertReturn(aMachine && aConsole, E_INVALIDARG);
+    AssertReturn(aMachine, E_INVALIDARG);
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -495,7 +515,7 @@ HRESULT Session::uninitialize()
                         VBOX_E_INVALID_VM_STATE);
 
         /* close ourselves */
-        rc = unlockMachine(false /* aFinalRelease */, true /* aFromServer */);
+        rc = i_unlockMachine(false /* aFinalRelease */, true /* aFromServer */);
     }
     else if (getObjectState().getState() == ObjectState::InUninit)
     {
@@ -720,6 +740,7 @@ HRESULT Session::onDnDModeChange(DnDMode_T aDndMode)
     AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
 #ifndef VBOX_COM_INPROC_API_CLIENT
     AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
+    AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
 
     return mConsole->i_onDnDModeChange(aDndMode);
 #else
@@ -910,6 +931,23 @@ HRESULT Session::onlineMergeMedium(const ComPtr<IMediumAttachment> &aMediumAttac
 #endif
 }
 
+HRESULT Session::reconfigureMediumAttachments(const std::vector<ComPtr<IMediumAttachment> > &aAttachments)
+{
+    if (mState != SessionState_Locked)
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Machine is not locked by session (session state: %s)."),
+                        Global::stringifySessionState(mState));
+#ifndef VBOX_COM_INPROC_API_CLIENT
+    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
+    AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
+
+    return mConsole->i_reconfigureMediumAttachments(aAttachments);
+#else
+    AssertFailed();
+    return E_NOTIMPL;
+#endif
+}
+
 HRESULT Session::enableVMMStatistics(BOOL aEnable)
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -950,14 +988,34 @@ HRESULT Session::resumeWithReason(Reason_T aReason)
 #ifndef VBOX_COM_INPROC_API_CLIENT
     AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
 
-    return mConsole->i_resume(aReason);
+    AutoWriteLock dummyLock(mConsole COMMA_LOCKVAL_SRC_POS);
+    return mConsole->i_resume(aReason, dummyLock);
+#else
+    AssertFailed();
+    return E_NOTIMPL;
+#endif
+}
+
+HRESULT Session::saveStateWithReason(Reason_T aReason, const ComPtr<IProgress> &aProgress, const Utf8Str &aStateFilePath, BOOL aPauseVM, BOOL *aLeftPaused)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
+    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
+#ifndef VBOX_COM_INPROC_API_CLIENT
+    AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
+
+    bool fLeftPaused = false;
+    HRESULT rc = mConsole->i_saveState(aReason, aProgress, aStateFilePath, !!aPauseVM, fLeftPaused);
+    if (aLeftPaused)
+        *aLeftPaused = fLeftPaused;
+    return rc;
 #else
     AssertFailed();
     return E_NOTIMPL;
 #endif
 }
 
-HRESULT Session::saveStateWithReason(Reason_T aReason, ComPtr<IProgress> &aProgress)
+HRESULT Session::cancelSaveStateWithReason()
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
@@ -965,7 +1023,7 @@ HRESULT Session::saveStateWithReason(Reason_T aReason, ComPtr<IProgress> &aProgr
 #ifndef VBOX_COM_INPROC_API_CLIENT
     AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
 
-    return mConsole->i_saveState(aReason, aProgress.asOutParam());
+    return mConsole->i_cancelSaveState();
 #else
     AssertFailed();
     return E_NOTIMPL;
@@ -984,7 +1042,7 @@ HRESULT Session::saveStateWithReason(Reason_T aReason, ComPtr<IProgress> &aProgr
  *  @note To be called only from #uninit(), #UnlockMachine() or #Uninitialize().
  *  @note Locks this object for writing.
  */
-HRESULT Session::unlockMachine(bool aFinalRelease, bool aFromServer)
+HRESULT Session::i_unlockMachine(bool aFinalRelease, bool aFromServer)
 {
     LogFlowThisFuncEnter();
     LogFlowThisFunc(("aFinalRelease=%d, isFromServer=%d\n",
diff --git a/src/VBox/Main/src-server/ApplianceImpl.cpp b/src/VBox/Main/src-server/ApplianceImpl.cpp
index 7dbea0e..86f1108 100644
--- a/src/VBox/Main/src-server/ApplianceImpl.cpp
+++ b/src/VBox/Main/src-server/ApplianceImpl.cpp
@@ -403,6 +403,8 @@ HRESULT Appliance::init(VirtualBox *aVirtualBox)
 
     // initialize data
     m = new Data;
+    m->m_pSecretKeyStore = new SecretKeyStore(false /* fRequireNonPageable*/);
+    AssertReturn(m->m_pSecretKeyStore, E_FAIL);
 
     i_initApplianceIONameMap();
 
@@ -425,6 +427,9 @@ void Appliance::uninit()
     if (autoUninitSpan.uninitDone())
         return;
 
+    if (m->m_pSecretKeyStore)
+        delete m->m_pSecretKeyStore;
+
     delete m;
     m = NULL;
 }
@@ -600,6 +605,52 @@ HRESULT Appliance::getWarnings(std::vector<com::Utf8Str> &aWarnings)
     return S_OK;
 }
 
+HRESULT Appliance::getPasswordIds(std::vector<com::Utf8Str> &aIdentifiers)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    aIdentifiers = m->m_vecPasswordIdentifiers;
+    return S_OK;
+}
+
+HRESULT Appliance::addPasswords(const std::vector<com::Utf8Str> &aIdentifiers,
+                                const std::vector<com::Utf8Str> &aPasswords)
+{
+    HRESULT hrc = S_OK;
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    /* Check that the IDs do not exist already before changing anything. */
+    for (unsigned i = 0; i < aIdentifiers.size(); i++)
+    {
+        SecretKey *pKey = NULL;
+        int rc = m->m_pSecretKeyStore->retainSecretKey(aIdentifiers[i], &pKey);
+        if (rc != VERR_NOT_FOUND)
+        {
+            AssertPtr(pKey);
+            if (pKey)
+                pKey->release();
+            return setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists"));
+        }
+    }
+
+    for (unsigned i = 0; i < aIdentifiers.size() && SUCCEEDED(hrc); i++)
+    {
+        size_t cbKey = aPasswords[i].length() + 1; /* Include terminator */
+        const uint8_t *pbKey = (const uint8_t *)aPasswords[i].c_str();
+
+        int rc = m->m_pSecretKeyStore->addSecretKey(aIdentifiers[i], pbKey, cbKey);
+        if (RT_SUCCESS(rc))
+            m->m_cPwProvided++;
+        else if (rc == VERR_NO_MEMORY)
+            hrc = setError(E_OUTOFMEMORY, tr("Failed to allocate enough secure memory for the key"));
+        else
+            hrc = setError(E_FAIL, tr("Unknown error happened while adding a password (%Rrc)"), rc);
+    }
+
+    return hrc;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 // Appliance private methods
diff --git a/src/VBox/Main/src-server/ApplianceImplExport.cpp b/src/VBox/Main/src-server/ApplianceImplExport.cpp
index 07a07ef..789a40c 100644
--- a/src/VBox/Main/src-server/ApplianceImplExport.cpp
+++ b/src/VBox/Main/src-server/ApplianceImplExport.cpp
@@ -357,6 +357,28 @@ HRESULT Machine::exportTo(const ComPtr<IAppliance> &aAppliance, const com::Utf8S
 
                 rc = pBaseMedium->COMGETTER(Size)(&llSize);
                 if (FAILED(rc)) throw rc;
+
+                /* If the medium is encrypted add the key identifier to the */
+                IMedium *iBaseMedium = pBaseMedium;
+                Medium *pBase = static_cast<Medium*>(iBaseMedium);
+                const com::Utf8Str strKeyId = pBase->i_getKeyId();
+                if (!strKeyId.isEmpty())
+                {
+                    bool fKnown = false;
+
+                    /* Check whether the ID is already in our sequence, add it otherwise. */
+                    for (unsigned i = 0; i < pAppliance->m->m_vecPasswordIdentifiers.size(); i++)
+                    {
+                        if (strKeyId.equals(pAppliance->m->m_vecPasswordIdentifiers[i]))
+                        {
+                            fKnown = true;
+                            break;
+                        }
+                    }
+
+                    if (!fKnown)
+                        pAppliance->m->m_vecPasswordIdentifiers.push_back(strKeyId);
+                }
             }
             else if (   deviceType == DeviceType_DVD
                      && pMedium)
@@ -649,6 +671,11 @@ HRESULT Appliance::write(const com::Utf8Str &aFormat,
         return setError(VBOX_E_FILE_ERROR,
                         tr("Invalid format \"%s\" specified"), aFormat.c_str());
 
+    /* Check whether all passwords are supplied or error out. */
+    if (m->m_cPwProvided < m->m_vecPasswordIdentifiers.size())
+        return setError(VBOX_E_INVALID_OBJECT_STATE,
+                        tr("Appliance export failed because not all passwords were provided for all encrypted media"));
+
     /* as of OVF 2.0 we have to use SHA256 */
     m->fSha256 = ovfF >= ovf::OVFVersion_2_0;
 
@@ -2167,6 +2194,7 @@ HRESULT Appliance::i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, P
                     rc = pSourceDisk->i_exportFile(strTargetFilePath.c_str(),
                                                    format,
                                                    MediumVariant_VmdkStreamOptimized,
+                                                   m->m_pSecretKeyStore,
                                                    pIfIo,
                                                    pStorage,
                                                    pProgress2);
diff --git a/src/VBox/Main/src-server/HostDnsService.cpp b/src/VBox/Main/src-server/HostDnsService.cpp
index c41d585..8fc61cc 100644
--- a/src/VBox/Main/src-server/HostDnsService.cpp
+++ b/src/VBox/Main/src-server/HostDnsService.cpp
@@ -28,6 +28,7 @@
 #include <iprt/critsect.h>
 
 #include <algorithm>
+#include <set>
 #include <string>
 #include "HostDnsService.h"
 
@@ -37,41 +38,24 @@ static HostDnsMonitor *g_monitor;
 static void dumpHostDnsInformation(const HostDnsInformation&);
 static void dumpHostDnsStrVector(const std::string&, const std::vector<std::string>&);
 
-/* Lockee */
-Lockee::Lockee()
-{
-    RTCritSectInit(&mLock);
-}
-
-Lockee::~Lockee()
-{
-    RTCritSectDelete(&mLock);
-}
-
-const RTCRITSECT* Lockee::lock() const
-{
-    return &mLock;
-}
-
-/* ALock */
-ALock::ALock(const Lockee *aLockee)
-  : lockee(aLockee)
-{
-    RTCritSectEnter(const_cast<PRTCRITSECT>(lockee->lock()));
-}
 
-ALock::~ALock()
+bool HostDnsInformation::equals(const HostDnsInformation &info, bool fDNSOrderIgnore) const
 {
-    RTCritSectLeave(const_cast<PRTCRITSECT>(lockee->lock()));
-}
-
-/* HostDnsInformation */
+    if (fDNSOrderIgnore)
+    {
+        std::set<std::string> l(servers.begin(), servers.end());
+        std::set<std::string> r(info.servers.begin(), info.servers.end());
 
-bool HostDnsInformation::equals(const HostDnsInformation &info) const
-{
-    return    (servers == info.servers)
-           && (domain == info.domain)
-           && (searchList == info.searchList);
+        return (l == r)
+            && (domain == info.domain)
+            && (searchList == info.searchList); // XXX: also ignore order?
+    }
+    else
+    {
+        return (servers == info.servers)
+            && (domain == info.domain)
+            && (searchList == info.searchList);
+    }
 }
 
 inline static void detachVectorOfString(const std::vector<std::string>& v,
@@ -85,12 +69,14 @@ inline static void detachVectorOfString(const std::vector<std::string>& v,
 
 struct HostDnsMonitor::Data
 {
-    Data(bool aThreaded) :
+    Data(bool aThreaded)
+      : fDNSOrderIgnore(false),
         fThreaded(aThreaded)
     {}
 
     std::vector<PCHostDnsMonitorProxy> proxies;
     HostDnsInformation info;
+    bool fDNSOrderIgnore;
     const bool fThreaded;
     RTTHREAD hMonitoringThread;
     RTSEMEVENT hDnsInitEvent;
@@ -98,7 +84,7 @@ struct HostDnsMonitor::Data
 
 struct HostDnsMonitorProxy::Data
 {
-    Data(const HostDnsMonitor *aMonitor, const VirtualBox *aParent)
+    Data(const HostDnsMonitor *aMonitor, VirtualBox *aParent)
       : info(NULL)
       , virtualbox(aParent)
       , monitor(aMonitor)
@@ -115,7 +101,7 @@ struct HostDnsMonitorProxy::Data
     }
 
     HostDnsInformation *info;
-    const VirtualBox *virtualbox;
+    VirtualBox *virtualbox;
     const HostDnsMonitor *monitor;
     bool fModified;
 };
@@ -136,7 +122,7 @@ HostDnsMonitor::~HostDnsMonitor()
     }
 }
 
-const HostDnsMonitor *HostDnsMonitor::getHostDnsMonitor()
+const HostDnsMonitor *HostDnsMonitor::getHostDnsMonitor(VirtualBox *aParent)
 {
     /* XXX: Moved initialization from HostImpl.cpp */
     if (!g_monitor)
@@ -156,7 +142,7 @@ const HostDnsMonitor *HostDnsMonitor::getHostDnsMonitor()
 # else
         g_monitor = new HostDnsService();
 # endif
-        g_monitor->init();
+        g_monitor->init(aParent);
     }
 
     return g_monitor;
@@ -164,14 +150,14 @@ const HostDnsMonitor *HostDnsMonitor::getHostDnsMonitor()
 
 void HostDnsMonitor::addMonitorProxy(PCHostDnsMonitorProxy proxy) const
 {
-    ALock l(this);
+    RTCLock grab(m_LockMtx);
     m->proxies.push_back(proxy);
     proxy->notify();
 }
 
 void HostDnsMonitor::releaseMonitorProxy(PCHostDnsMonitorProxy proxy) const
 {
-    ALock l(this);
+    RTCLock grab(m_LockMtx);
     std::vector<PCHostDnsMonitorProxy>::iterator it;
     it = std::find(m->proxies.begin(), m->proxies.end(), proxy);
 
@@ -197,7 +183,7 @@ const HostDnsInformation &HostDnsMonitor::getInfo() const
 
 void HostDnsMonitor::setInfo(const HostDnsInformation &info)
 {
-    ALock l(this);
+    RTCLock grab(m_LockMtx);
 
     if (info.equals(m->info))
         return;
@@ -207,15 +193,37 @@ void HostDnsMonitor::setInfo(const HostDnsInformation &info)
     LogRel(("HostDnsMonitor: new information\n"));
     dumpHostDnsInformation(info);
 
+    bool fIgnore = m->fDNSOrderIgnore && info.equals(m->info, m->fDNSOrderIgnore);
     m->info = info;
 
+    if (fIgnore)
+    {
+        LogRel(("HostDnsMonitor: order change only, not notifying\n"));
+        return;
+    }
+
     std::vector<PCHostDnsMonitorProxy>::const_iterator it;
     for (it = m->proxies.begin(); it != m->proxies.end(); ++it)
         (*it)->notify();
 }
 
-HRESULT HostDnsMonitor::init()
+HRESULT HostDnsMonitor::init(VirtualBox *virtualbox)
 {
+    const com::Bstr bstrHostDNSOrderIgnoreKey("VBoxInternal2/HostDNSOrderIgnore");
+    com::Bstr bstrHostDNSOrderIgnore;
+    virtualbox->GetExtraData(bstrHostDNSOrderIgnoreKey.raw(),
+                             bstrHostDNSOrderIgnore.asOutParam());
+
+    if (bstrHostDNSOrderIgnore.isNotEmpty())
+    {
+        LogRel(("HostDnsMonitor: %ls=%ls\n",
+                bstrHostDNSOrderIgnoreKey.raw(),
+                bstrHostDNSOrderIgnore.raw()));
+
+        if (bstrHostDNSOrderIgnore != "0")
+            m->fDNSOrderIgnore = true;
+    }
+
     if (m->fThreaded)
     {
         int rc = RTSemEventCreate(&m->hDnsInitEvent);
@@ -261,7 +269,7 @@ HostDnsMonitorProxy::~HostDnsMonitorProxy()
     }
 }
 
-void HostDnsMonitorProxy::init(const HostDnsMonitor *mon, const VirtualBox* aParent)
+void HostDnsMonitorProxy::init(const HostDnsMonitor *mon, VirtualBox* aParent)
 {
     m = new HostDnsMonitorProxy::Data(mon, aParent);
     m->monitor->addMonitorProxy(this);
@@ -272,13 +280,13 @@ void HostDnsMonitorProxy::notify() const
 {
     LogRel(("HostDnsMonitorProxy::notify\n"));
     m->fModified = true;
-    const_cast<VirtualBox *>(m->virtualbox)->i_onHostNameResolutionConfigurationChange();
+    m->virtualbox->i_onHostNameResolutionConfigurationChange();
 }
 
 HRESULT HostDnsMonitorProxy::GetNameServers(std::vector<com::Utf8Str> &aNameServers)
 {
     AssertReturn(m && m->info, E_FAIL);
-    ALock l(this);
+    RTCLock grab(m_LockMtx);
 
     if (m->fModified)
         updateInfo();
@@ -294,7 +302,7 @@ HRESULT HostDnsMonitorProxy::GetNameServers(std::vector<com::Utf8Str> &aNameServ
 HRESULT HostDnsMonitorProxy::GetDomainName(com::Utf8Str *pDomainName)
 {
     AssertReturn(m && m->info, E_FAIL);
-    ALock l(this);
+    RTCLock grab(m_LockMtx);
 
     if (m->fModified)
         updateInfo();
@@ -310,7 +318,7 @@ HRESULT HostDnsMonitorProxy::GetDomainName(com::Utf8Str *pDomainName)
 HRESULT HostDnsMonitorProxy::GetSearchStrings(std::vector<com::Utf8Str> &aSearchStrings)
 {
     AssertReturn(m && m->info, E_FAIL);
-    ALock l(this);
+    RTCLock grab(m_LockMtx);
 
     if (m->fModified)
         updateInfo();
diff --git a/src/VBox/Main/src-server/HostDnsService.h b/src/VBox/Main/src-server/HostDnsService.h
index d7c574a..2861d34 100644
--- a/src/VBox/Main/src-server/HostDnsService.h
+++ b/src/VBox/Main/src-server/HostDnsService.h
@@ -20,8 +20,8 @@
 #include "VirtualBoxBase.h"
 
 #include <iprt/cdefs.h>
-#include <iprt/critsect.h>
 #include <iprt/types.h>
+#include <iprt/cpp/lock.h>
 
 #include <list>
 #include <vector>
@@ -32,44 +32,23 @@ typedef Utf8StrList::iterator Utf8StrListIterator;
 class HostDnsMonitorProxy;
 typedef const HostDnsMonitorProxy *PCHostDnsMonitorProxy;
 
-class Lockee
-{
-  public:
-    Lockee();
-    virtual ~Lockee();
-    const RTCRITSECT* lock() const;
-
-  private:
-    RTCRITSECT mLock;
-};
-
-class ALock
-{
-  public:
-    explicit ALock(const Lockee *l);
-    ~ALock();
-
-  private:
-    const Lockee *lockee;
-};
-
 class HostDnsInformation
 {
   public:
     std::vector<std::string> servers;
     std::string domain;
     std::vector<std::string> searchList;
-    bool equals(const HostDnsInformation &) const;
+    bool equals(const HostDnsInformation &, bool fDNSOrderIgnore = false) const;
 };
 
 /**
  * This class supposed to be a real DNS monitor object it should be singleton,
  * it lifecycle starts and ends together with VBoxSVC.
  */
-class HostDnsMonitor : public Lockee
+class HostDnsMonitor
 {
   public:
-    static const HostDnsMonitor *getHostDnsMonitor();
+    static const HostDnsMonitor *getHostDnsMonitor(VirtualBox *virtualbox);
     static void shutdown();
 
     void addMonitorProxy(PCHostDnsMonitorProxy) const;
@@ -77,7 +56,7 @@ class HostDnsMonitor : public Lockee
     const HostDnsInformation &getInfo() const;
     /* @note: method will wait till client call
        HostDnsService::monitorThreadInitializationDone() */
-    virtual HRESULT init();
+    virtual HRESULT init(VirtualBox *virtualbox);
 
   protected:
     explicit HostDnsMonitor(bool fThreaded = false);
@@ -95,6 +74,9 @@ class HostDnsMonitor : public Lockee
     HostDnsMonitor& operator= (const HostDnsMonitor &);
     static int threadMonitoringRoutine(RTTHREAD, void *);
 
+  protected:
+    mutable RTCLockMtx m_LockMtx;
+
   public:
     struct Data;
     Data *m;
@@ -103,12 +85,12 @@ class HostDnsMonitor : public Lockee
 /**
  * This class supposed to be a proxy for events on changing Host Name Resolving configurations.
  */
-class HostDnsMonitorProxy : public Lockee
+class HostDnsMonitorProxy
 {
     public:
     HostDnsMonitorProxy();
     ~HostDnsMonitorProxy();
-    void init(const HostDnsMonitor *aMonitor, const VirtualBox *aParent);
+    void init(const HostDnsMonitor *aMonitor, VirtualBox *virtualbox);
     void notify() const;
 
     HRESULT GetNameServers(std::vector<com::Utf8Str> &aNameServers);
@@ -119,6 +101,9 @@ class HostDnsMonitorProxy : public Lockee
 
     private:
     void updateInfo();
+ 
+  private:
+    mutable RTCLockMtx m_LockMtx;
 
     private:
     struct Data;
@@ -131,7 +116,7 @@ class HostDnsServiceDarwin : public HostDnsMonitor
   public:
     HostDnsServiceDarwin();
     ~HostDnsServiceDarwin();
-    HRESULT init();
+    virtual HRESULT init(VirtualBox *virtualbox);
 
     protected:
     virtual void monitorThreadShutdown();
@@ -150,7 +135,7 @@ class HostDnsServiceWin : public HostDnsMonitor
     public:
     HostDnsServiceWin();
     ~HostDnsServiceWin();
-    HRESULT init();
+    virtual HRESULT init(VirtualBox *virtualbox);
 
     protected:
     virtual void monitorThreadShutdown();
@@ -170,7 +155,7 @@ class HostDnsServiceResolvConf: public HostDnsMonitor
   public:
     explicit HostDnsServiceResolvConf(bool fThreaded = false) : HostDnsMonitor(fThreaded), m(NULL) {}
     virtual ~HostDnsServiceResolvConf();
-    virtual HRESULT init(const char *aResolvConfFileName);
+    virtual HRESULT init(VirtualBox *virtualbox, const char *aResolvConfFileName);
     const std::string& resolvConf() const;
 
   protected:
@@ -194,7 +179,9 @@ class HostDnsServiceSolaris : public HostDnsServiceResolvConf
   public:
     HostDnsServiceSolaris(){}
     ~HostDnsServiceSolaris(){}
-    HRESULT init(){ return HostDnsServiceResolvConf::init("/etc/resolv.conf");}
+    virtual HRESULT init(VirtualBox *virtualbox) {
+	return HostDnsServiceResolvConf::init(virtualbox, "/etc/resolv.conf");
+    }
 };
 
 #  elif defined(RT_OS_LINUX)
@@ -203,7 +190,9 @@ class HostDnsServiceLinux : public HostDnsServiceResolvConf
   public:
     HostDnsServiceLinux():HostDnsServiceResolvConf(true){}
     virtual ~HostDnsServiceLinux();
-    virtual HRESULT init(){ return HostDnsServiceResolvConf::init("/etc/resolv.conf");}
+    virtual HRESULT init(VirtualBox *virtualbox) {
+	return HostDnsServiceResolvConf::init(virtualbox, "/etc/resolv.conf");
+    }
 
   protected:
     virtual void monitorThreadShutdown();
@@ -216,7 +205,9 @@ class HostDnsServiceFreebsd: public HostDnsServiceResolvConf
     public:
     HostDnsServiceFreebsd(){}
     ~HostDnsServiceFreebsd(){}
-    HRESULT init(){ return HostDnsServiceResolvConf::init("/etc/resolv.conf");}
+    virtual HRESULT init(VirtualBox *virtualbox) {
+	return HostDnsServiceResolvConf::init(virtualbox, "/etc/resolv.conf");
+    }
 };
 
 #  elif defined(RT_OS_OS2)
@@ -226,7 +217,9 @@ class HostDnsServiceOs2 : public HostDnsServiceResolvConf
     HostDnsServiceOs2(){}
     ~HostDnsServiceOs2(){}
     /* XXX: \\MPTN\\ETC should be taken from environment variable ETC  */
-    HRESULT init(){ return init("\\MPTN\\ETC\\RESOLV2");}
+    virtual HRESULT init(VirtualBox *virtualbox) {
+	return HostDnsServiceResolvConf::init(virtualbox, "\\MPTN\\ETC\\RESOLV2");
+    }
 };
 
 #  endif
diff --git a/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp b/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
index e580051..ffc99e4 100644
--- a/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
+++ b/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
@@ -66,11 +66,11 @@ HostDnsServiceResolvConf::~HostDnsServiceResolvConf()
     }
 }
 
-HRESULT HostDnsServiceResolvConf::init(const char *aResolvConfFileName)
+HRESULT HostDnsServiceResolvConf::init(VirtualBox *virtualbox, const char *aResolvConfFileName)
 {
     m = new Data(aResolvConfFileName);
 
-    HostDnsMonitor::init();
+    HostDnsMonitor::init(virtualbox);
 
     readResolvConf();
 
diff --git a/src/VBox/Main/src-server/HostImpl.cpp b/src/VBox/Main/src-server/HostImpl.cpp
index 25a0530..e35774d 100644
--- a/src/VBox/Main/src-server/HostImpl.cpp
+++ b/src/VBox/Main/src-server/HostImpl.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2004-2014 Oracle Corporation
+ * Copyright (C) 2004-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -299,7 +299,7 @@ HRESULT Host::init(VirtualBox *aParent)
     /* Create the list of network interfaces so their metrics get registered. */
     i_updateNetIfList();
 
-    m->hostDnsMonitorProxy.init(HostDnsMonitor::getHostDnsMonitor(), m->pParent);
+    m->hostDnsMonitorProxy.init(HostDnsMonitor::getHostDnsMonitor(m->pParent), m->pParent);
 
 #if defined(RT_OS_WINDOWS)
     m->pHostPowerService = new HostPowerServiceWin(m->pParent);
@@ -613,12 +613,15 @@ static int vboxNetWinAddComponent(std::list< ComObjPtr<HostNetworkInterface> > *
 HRESULT Host::getNetworkInterfaces(std::vector<ComPtr<IHostNetworkInterface> > &aNetworkInterfaces)
 {
 #if defined(RT_OS_WINDOWS) || defined(VBOX_WITH_NETFLT) /*|| defined(RT_OS_OS2)*/
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
 # ifdef VBOX_WITH_HOSTNETIF_API
-    int rc = i_updateNetIfList();
-    if (rc)
-        Log(("Failed to get host network interface list with rc=%Rrc\n", rc));
+    HRESULT rc = i_updateNetIfList();
+    if (FAILED(rc))
+    {
+        Log(("Failed to update host network interface list with rc=%Rhrc\n", rc));
+        return rc;
+    }
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     aNetworkInterfaces.resize(m->llNetIfs.size());
     size_t i = 0;
@@ -1485,17 +1488,16 @@ HRESULT Host::findHostNetworkInterfaceByName(const com::Utf8Str &aName,
     if (!aName.length())
         return E_INVALIDARG;
 
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+    HRESULT rc = i_updateNetIfList();
+    if (FAILED(rc))
+    {
+        Log(("Failed to update host network interface list with rc=%Rhrc\n", rc));
+        return rc;
+    }
 
-    aNetworkInterface = NULL;
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     ComObjPtr<HostNetworkInterface> found;
-    int rc = i_updateNetIfList();
-    if (RT_FAILURE(rc))
-    {
-        Log(("Failed to get host network interface list with rc=%Rrc\n", rc));
-        return E_FAIL;
-    }
     for (HostNetworkInterfaceList::iterator it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
     {
         Bstr n;
@@ -1521,19 +1523,17 @@ HRESULT Host::findHostNetworkInterfaceById(const com::Guid &aId,
     if (!aId.isValid())
         return E_INVALIDARG;
 
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+    HRESULT rc = i_updateNetIfList();
+    if (FAILED(rc))
+    {
+        Log(("Failed to update host network interface list with rc=%Rhrc\n", rc));
+        return rc;
+    }
 
-    aNetworkInterface = NULL;
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     ComObjPtr<HostNetworkInterface> found;
-    int rc = i_updateNetIfList();
-    if (RT_FAILURE(rc))
-    {
-        Log(("Failed to get host network interface list with rc=%Rrc\n", rc));
-        return E_FAIL;
-    }
-    HostNetworkInterfaceList::iterator it;
-    for (it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
+    for (HostNetworkInterfaceList::iterator it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
     {
         Bstr g;
         (*it)->COMGETTER(Id)(g.asOutParam());
@@ -1553,13 +1553,16 @@ HRESULT Host::findHostNetworkInterfacesOfType(HostNetworkInterfaceType_T aType,
                                               std::vector<ComPtr<IHostNetworkInterface> > &aNetworkInterfaces)
 {
 #ifdef VBOX_WITH_HOSTNETIF_API
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-    int rc = i_updateNetIfList();
-    if (RT_FAILURE(rc))
-        return E_FAIL;
+    HRESULT rc = i_updateNetIfList();
+    if (FAILED(rc))
+    {
+        Log(("Failed to update host network interface list with rc=%Rhrc\n", rc));
+        return rc;
+    }
 
-    HostNetworkInterfaceList resultList;
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
+    HostNetworkInterfaceList resultList;
     for (HostNetworkInterfaceList::iterator it = m->llNetIfs.begin(); it != m->llNetIfs.end(); ++it)
     {
         HostNetworkInterfaceType_T t;
@@ -2950,19 +2953,26 @@ HRESULT Host::i_checkUSBProxyService()
 HRESULT Host::i_updateNetIfList()
 {
 #ifdef VBOX_WITH_HOSTNETIF_API
-    AssertReturn(   getObjectState().getState() == ObjectState::InInit
-                 || isWriteLockOnCurrentThread(), E_FAIL);
-
-    HostNetworkInterfaceList list, listCopy;
+    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
+
+    /** @todo r=klaus it would save lots of clock cycles if for concurrent
+     * threads executing this code we'd only do one interface enumeration
+     * and update, and let the other threads use the result as is. However
+     * if there's a constant hammering of this method, we don't want this
+     * to cause update starvation. */
+    HostNetworkInterfaceList list;
     int rc = NetIfList(list);
     if (rc)
     {
         Log(("Failed to get host network interface list with rc=%Rrc\n", rc));
         return E_FAIL;
     }
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     AssertReturn(m->pParent, E_FAIL);
     /* Make a copy as the original may be partially destroyed later. */
-    listCopy = list;
+    HostNetworkInterfaceList listCopy(list);
     HostNetworkInterfaceList::iterator itOld, itNew;
 # ifdef VBOX_WITH_RESOURCE_USAGE_API
     PerformanceCollector *aCollector = m->pParent->i_performanceCollector();
@@ -3000,8 +3010,8 @@ HRESULT Host::i_updateNetIfList()
     for (itNew = listCopy.begin(); itNew != listCopy.end(); ++itNew)
     {
         HostNetworkInterfaceType_T t;
-        HRESULT hr = (*itNew)->COMGETTER(InterfaceType)(&t);
-        if (FAILED(hr))
+        HRESULT hrc = (*itNew)->COMGETTER(InterfaceType)(&t);
+        if (FAILED(hrc))
         {
             Bstr n;
             (*itNew)->COMGETTER(Name)(n.asOutParam());
diff --git a/src/VBox/Main/src-server/HostPower.cpp b/src/VBox/Main/src-server/HostPower.cpp
index 2d3847c..d5e573c 100644
--- a/src/VBox/Main/src-server/HostPower.cpp
+++ b/src/VBox/Main/src-server/HostPower.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -138,12 +138,11 @@ void HostPowerService::notify(Reason_T aReason)
             size_t saved = 0;
 
             /* save running VMs */
-            SessionMachinesList::const_iterator it2 = machines.begin();
-            for (VirtualBox::InternalControlList::const_iterator it = controls.begin();
-                 it != controls.end() && it2 != machines.end();
-                 ++it, ++it2)
+            for (SessionMachinesList::const_iterator it = machines.begin();
+                 it != machines.end();
+                 ++it)
             {
-                ComPtr<SessionMachine> pMachine = *it2;
+                ComPtr<SessionMachine> pMachine = *it;
                 rc = pMachine->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(),
                                             value.asOutParam());
                 int fPerVM = 0;
@@ -159,12 +158,11 @@ void HostPowerService::notify(Reason_T aReason)
                 /* default is true */
                 if (fGlobal + fPerVM >= 0)
                 {
-                    ComPtr<IInternalSessionControl> pControl = *it;
                     ComPtr<IProgress> progress;
 
-                    /* note that SaveStateWithReason() will simply return a failure
-                     * if the VM is in an inappropriate state */
-                    rc = pControl->SaveStateWithReason(Reason_HostBatteryLow, progress.asOutParam());
+                    /* SessionMachine::i_saveStateWithReason() will return
+                     * a failure if the VM is in an inappropriate state */
+                    rc = pMachine->i_saveStateWithReason(Reason_HostBatteryLow, progress);
                     if (FAILED(rc))
                     {
                         LogRel(("SaveState '%s' failed with %Rhrc\n", pMachine->i_getName().c_str(), rc));
diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp
index 7b5b84c..d8e5ba6 100644
--- a/src/VBox/Main/src-server/MachineImpl.cpp
+++ b/src/VBox/Main/src-server/MachineImpl.cpp
@@ -130,6 +130,7 @@ Machine::Data::Data()
     mGuestPropertiesModified   = FALSE;
 
     mSession.mPID              = NIL_RTPROCESS;
+    mSession.mLockType         = LockType_Null;
     mSession.mState            = SessionState_Unlocked;
 }
 
@@ -2693,6 +2694,7 @@ HRESULT Machine::getState(MachineState_T *aState)
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     *aState = mData->mMachineState;
+    Assert(mData->mMachineState != MachineState_Null);
 
     return S_OK;
 }
@@ -3247,6 +3249,7 @@ HRESULT Machine::lockMachine(const ComPtr<ISession> &aSession,
         // 3) process W: the process which already holds the write lock on the machine (write-locking session)
 
         // copy pointers to W (the write-locking session) before leaving lock (these must not be NULL)
+        ComAssertRet(mData->mSession.mLockType == LockType_Write || mData->mSession.mLockType == LockType_VM, E_FAIL);
         ComPtr<IInternalSessionControl> pSessionW = mData->mSession.mDirectControl;
         ComAssertRet(!pSessionW.isNull(), E_FAIL);
         ComObjPtr<SessionMachine> pSessionMachine = mData->mSession.mMachine;
@@ -3262,15 +3265,17 @@ HRESULT Machine::lockMachine(const ComPtr<ISession> &aSession,
 
         // get the console of the session holding the write lock (this is a remote call)
         ComPtr<IConsole> pConsoleW;
-        LogFlowThisFunc(("Calling GetRemoteConsole()...\n"));
-        rc = pSessionW->GetRemoteConsole(pConsoleW.asOutParam());
-        LogFlowThisFunc(("GetRemoteConsole() returned %08X\n", rc));
-        if (FAILED(rc))
-            // the failure may occur w/o any error info (from RPC), so provide one
-            return setError(VBOX_E_VM_ERROR,
-                            tr("Failed to get a console object from the direct session (%Rhrc)"), rc);
-
-        ComAssertRet(!pConsoleW.isNull(), E_FAIL);
+        if (mData->mSession.mLockType == LockType_VM)
+        {
+            LogFlowThisFunc(("Calling GetRemoteConsole()...\n"));
+            rc = pSessionW->COMGETTER(RemoteConsole)(pConsoleW.asOutParam());
+            LogFlowThisFunc(("GetRemoteConsole() returned %08X\n", rc));
+            if (FAILED(rc))
+                // the failure may occur w/o any error info (from RPC), so provide one
+                return setError(VBOX_E_VM_ERROR,
+                                tr("Failed to get a console object from the direct session (%Rhrc)"), rc);
+            ComAssertRet(!pConsoleW.isNull(), E_FAIL);
+        }
 
         // share the session machine and W's console with the caller's session
         LogFlowThisFunc(("Calling AssignRemoteMachine()...\n"));
@@ -3314,7 +3319,7 @@ HRESULT Machine::lockMachine(const ComPtr<ISession> &aSession,
         // get the caller's session PID
         RTPROCESS pid = NIL_RTPROCESS;
         AssertCompile(sizeof(ULONG) == sizeof(RTPROCESS));
-        pSessionControl->GetPID((ULONG*)&pid);
+        pSessionControl->COMGETTER(PID)((ULONG*)&pid);
         Assert(pid != NIL_RTPROCESS);
 
         bool fLaunchingVMProcess = (mData->mSession.mState == SessionState_Spawning);
@@ -3431,7 +3436,7 @@ HRESULT Machine::lockMachine(const ComPtr<ISession> &aSession,
 
                 /* get the console from the direct session */
                 ComPtr<IConsole> console;
-                rc = pSessionControl->GetRemoteConsole(console.asOutParam());
+                rc = pSessionControl->COMGETTER(RemoteConsole)(console.asOutParam());
                 ComAssertComRC(rc);
 
                 if (SUCCEEDED(rc) && !console)
@@ -3504,6 +3509,7 @@ HRESULT Machine::lockMachine(const ComPtr<ISession> &aSession,
 
         if (SUCCEEDED(rc))
         {
+            mData->mSession.mLockType = aLockType;
             /* memorize the direct session control and cache IUnknown for it */
             mData->mSession.mDirectControl = pSessionControl;
             mData->mSession.mState = SessionState_Locked;
@@ -3524,7 +3530,6 @@ HRESULT Machine::lockMachine(const ComPtr<ISession> &aSession,
         /* uninitialize the created session machine on failure */
         if (FAILED(rc))
             sessionMachine->uninit();
-
     }
 
     if (SUCCEEDED(rc))
@@ -4924,7 +4929,7 @@ HRESULT Machine::setExtraData(const com::Utf8Str &aKey, const com::Utf8Str &aVal
                             tr("Cannot set extradata for a snapshot"));
 
         // check if the right IMachine instance is used
-        if (!i_isSessionMachine())
+        if (mData->mRegistered && !i_isSessionMachine())
             return setError(VBOX_E_INVALID_VM_STATE,
                             tr("Cannot set extradata for an immutable machine"));
 
@@ -5171,116 +5176,56 @@ HRESULT Machine::unregister(CleanupMode_T aCleanupMode,
     return S_OK;
 }
 
-struct Machine::DeleteTask
-{
-    ComObjPtr<Machine>          pMachine;
-    RTCList<ComPtr<IMedium> >   llMediums;
-    StringsList                 llFilesToDelete;
-    ComObjPtr<Progress>         pProgress;
-};
-
-HRESULT Machine::deleteConfig(const std::vector<ComPtr<IMedium> > &aMedia, ComPtr<IProgress> &aProgress)
-{
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    HRESULT rc = i_checkStateDependency(MutableStateDep);
-    if (FAILED(rc)) return rc;
-
-    if (mData->mRegistered)
-        return setError(VBOX_E_INVALID_VM_STATE,
-                        tr("Cannot delete settings of a registered machine"));
-
-    DeleteTask *pTask = new DeleteTask;
-    pTask->pMachine = this;
-
-    // collect files to delete
-    pTask->llFilesToDelete = mData->llFilesToDelete;            // saved states pushed here by Unregister()
-
-    for (size_t i = 0; i < aMedia.size(); ++i)
-    {
-        IMedium *pIMedium(aMedia[i]);
-        ComObjPtr<Medium> pMedium = static_cast<Medium*>(pIMedium);
-        if (pMedium.isNull())
-            return setError(E_INVALIDARG, "The given medium pointer with index %d is invalid", i);
-        SafeArray<BSTR> ids;
-        rc = pMedium->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(ids));
-        if (FAILED(rc)) return rc;
-        /* At this point the medium should not have any back references
-         * anymore. If it has it is attached to another VM and *must* not
-         * deleted. */
-        if (ids.size() < 1)
-            pTask->llMediums.append(pMedium);
-    }
-    if (mData->pMachineConfigFile->fileExists())
-        pTask->llFilesToDelete.push_back(mData->m_strConfigFileFull);
-
-    pTask->pProgress.createObject();
-    pTask->pProgress->init(i_getVirtualBox(),
-                           static_cast<IMachine*>(this) /* aInitiator */,
-                           Bstr(tr("Deleting files")).raw(),
-                           true /* fCancellable */,
-                           (ULONG)(pTask->llFilesToDelete.size() + pTask->llMediums.size() + 1),   // cOperations
-                           BstrFmt(tr("Deleting '%s'"), pTask->llFilesToDelete.front().c_str()).raw());
-
-    int vrc = RTThreadCreate(NULL,
-                             Machine::deleteThread,
-                             (void*)pTask,
-                             0,
-                             RTTHREADTYPE_MAIN_WORKER,
-                             0,
-                             "MachineDelete");
-
-    pTask->pProgress.queryInterfaceTo(aProgress.asOutParam());
-
-    if (RT_FAILURE(vrc))
-    {
-        delete pTask;
-        return setError(E_FAIL, "Could not create MachineDelete thread (%Rrc)", vrc);
-    }
-
-    LogFlowFuncLeave();
-
-    return S_OK;
-}
-
 /**
- * Static task wrapper passed to RTThreadCreate() in Machine::Delete() which then
- * calls Machine::deleteTaskWorker() on the actual machine object.
- * @param Thread
- * @param pvUser
- * @return
+ * Task record for deleting a machine config.
  */
-/*static*/
-DECLCALLBACK(int) Machine::deleteThread(RTTHREAD Thread, void *pvUser)
+struct Machine::DeleteConfigTask
+    : public Machine::Task
 {
-    LogFlowFuncEnter();
-
-    DeleteTask *pTask = (DeleteTask*)pvUser;
-    Assert(pTask);
-    Assert(pTask->pMachine);
-    Assert(pTask->pProgress);
+    DeleteConfigTask(Machine *m,
+                     Progress *p,
+                     const Utf8Str &t,
+                     const RTCList<ComPtr<IMedium> > &llMediums,
+                     const StringsList &llFilesToDelete)
+        : Task(m, p, t),
+          m_llMediums(llMediums),
+          m_llFilesToDelete(llFilesToDelete)
+    {}
 
-    HRESULT rc = pTask->pMachine->i_deleteTaskWorker(*pTask);
-    pTask->pProgress->i_notifyComplete(rc);
-
-    delete pTask;
-
-    LogFlowFuncLeave();
-
-    NOREF(Thread);
+    void handler()
+    {
+        m_pMachine->i_deleteConfigHandler(*this);
+    }
 
-    return VINF_SUCCESS;
-}
+    RTCList<ComPtr<IMedium> >   m_llMediums;
+    StringsList                 m_llFilesToDelete;
+};
 
 /**
- * Task thread implementation for Machine::Delete(), called from Machine::deleteThread().
+ * Task thread implementation for SessionMachine::DeleteConfig(), called from
+ * SessionMachine::taskHandler().
+ *
+ * @note Locks this object for writing.
+ *
  * @param task
  * @return
  */
-HRESULT Machine::i_deleteTaskWorker(DeleteTask &task)
+void Machine::i_deleteConfigHandler(DeleteConfigTask &task)
 {
+    LogFlowThisFuncEnter();
+
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    LogFlowThisFunc(("state=%d\n", getObjectState().getState()));
+    if (FAILED(autoCaller.rc()))
+    {
+        /* we might have been uninitialized because the session was accidentally
+         * closed by the client, so don't assert */
+        HRESULT rc = setError(E_FAIL,
+                              tr("The session has been accidentally closed"));
+        task.m_pProgress->i_notifyComplete(rc);
+        LogFlowThisFuncLeave();
+        return;
+    }
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -5302,14 +5247,14 @@ HRESULT Machine::i_deleteTaskWorker(DeleteTask &task)
         MachineState_T oldState = mData->mMachineState;
         i_setMachineState(MachineState_SettingUp);
         alock.release();
-        for (size_t i = 0; i < task.llMediums.size(); ++i)
+        for (size_t i = 0; i < task.m_llMediums.size(); ++i)
         {
-            ComObjPtr<Medium> pMedium = (Medium*)(IMedium*)task.llMediums.at(i);
+            ComObjPtr<Medium> pMedium = (Medium*)(IMedium*)(task.m_llMediums.at(i));
             {
                 AutoCaller mac(pMedium);
                 if (FAILED(mac.rc())) throw mac.rc();
                 Utf8Str strLocation = pMedium->i_getLocationFull();
-                rc = task.pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), strLocation.c_str()).raw(), 1);
+                rc = task.m_pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), strLocation.c_str()).raw(), 1);
                 if (FAILED(rc)) throw rc;
                 LogFunc(("Deleting file %s\n", strLocation.c_str()));
             }
@@ -5318,7 +5263,7 @@ HRESULT Machine::i_deleteTaskWorker(DeleteTask &task)
                 ComPtr<IProgress> pProgress2;
                 rc = pMedium->DeleteStorage(pProgress2.asOutParam());
                 if (FAILED(rc)) throw rc;
-                rc = task.pProgress->WaitForAsyncProgressCompletion(pProgress2);
+                rc = task.m_pProgress->WaitForAsyncProgressCompletion(pProgress2);
                 if (FAILED(rc)) throw rc;
                 /* Check the result of the asynchronous process. */
                 LONG iRc;
@@ -5346,8 +5291,8 @@ HRESULT Machine::i_deleteTaskWorker(DeleteTask &task)
         // (this includes saved states of the machine and snapshots and
         // medium storage files from the IMedium list passed in, and the
         // machine XML file)
-        StringsList::const_iterator it = task.llFilesToDelete.begin();
-        while (it != task.llFilesToDelete.end())
+        StringsList::const_iterator it = task.m_llFilesToDelete.begin();
+        while (it != task.m_llFilesToDelete.end())
         {
             const Utf8Str &strFile = *it;
             LogFunc(("Deleting file %s\n", strFile.c_str()));
@@ -5357,14 +5302,14 @@ HRESULT Machine::i_deleteTaskWorker(DeleteTask &task)
                                tr("Could not delete file '%s' (%Rrc)"), strFile.c_str(), vrc);
 
             ++it;
-            if (it == task.llFilesToDelete.end())
+            if (it == task.m_llFilesToDelete.end())
             {
-                rc = task.pProgress->SetNextOperation(Bstr(tr("Cleaning up machine directory")).raw(), 1);
+                rc = task.m_pProgress->SetNextOperation(Bstr(tr("Cleaning up machine directory")).raw(), 1);
                 if (FAILED(rc)) throw rc;
                 break;
             }
 
-            rc = task.pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), it->c_str()).raw(), 1);
+            rc = task.m_pProgress->SetNextOperation(BstrFmt(tr("Deleting '%s'"), it->c_str()).raw(), 1);
             if (FAILED(rc)) throw rc;
         }
 
@@ -5437,7 +5382,67 @@ HRESULT Machine::i_deleteTaskWorker(DeleteTask &task)
     }
     catch (HRESULT aRC) { rc = aRC; }
 
-    return rc;
+    task.m_pProgress->i_notifyComplete(rc);
+
+    LogFlowThisFuncLeave();
+}
+
+HRESULT Machine::deleteConfig(const std::vector<ComPtr<IMedium> > &aMedia, ComPtr<IProgress> &aProgress)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    HRESULT rc = i_checkStateDependency(MutableStateDep);
+    if (FAILED(rc)) return rc;
+
+    if (mData->mRegistered)
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Cannot delete settings of a registered machine"));
+
+    // collect files to delete
+    StringsList llFilesToDelete(mData->llFilesToDelete);    // saved states pushed here by Unregister()
+    if (mData->pMachineConfigFile->fileExists())
+        llFilesToDelete.push_back(mData->m_strConfigFileFull);
+
+    RTCList<ComPtr<IMedium> > llMediums;
+    for (size_t i = 0; i < aMedia.size(); ++i)
+    {
+        IMedium *pIMedium(aMedia[i]);
+        ComObjPtr<Medium> pMedium = static_cast<Medium*>(pIMedium);
+        if (pMedium.isNull())
+            return setError(E_INVALIDARG, "The given medium pointer with index %d is invalid", i);
+        SafeArray<BSTR> ids;
+        rc = pMedium->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(ids));
+        if (FAILED(rc)) return rc;
+        /* At this point the medium should not have any back references
+         * anymore. If it has it is attached to another VM and *must* not
+         * deleted. */
+        if (ids.size() < 1)
+            llMediums.append(pMedium);
+    }
+
+    ComObjPtr<Progress> pProgress;
+    pProgress.createObject();
+    rc = pProgress->init(i_getVirtualBox(),
+                         static_cast<IMachine*>(this) /* aInitiator */,
+                         Bstr(tr("Deleting files")).raw(),
+                         true /* fCancellable */,
+                         (ULONG)(llFilesToDelete.size() + llMediums.size() + 1),   // cOperations
+                         BstrFmt(tr("Deleting '%s'"), llFilesToDelete.front().c_str()).raw());
+    if (FAILED(rc))
+        return rc;
+
+    /* create and start the task on a separate thread (note that it will not
+     * start working until we release alock) */
+    DeleteConfigTask *pTask = new DeleteConfigTask(this, pProgress, "DeleteVM", llMediums, llFilesToDelete);
+    rc = pTask->createThread();
+    if (FAILED(rc))
+        return rc;
+
+    pProgress.queryInterfaceTo(aProgress.asOutParam());
+
+    LogFlowFuncLeave();
+
+    return S_OK;
 }
 
 HRESULT Machine::findSnapshot(const com::Utf8Str &aNameOrId, ComPtr<ISnapshot> &aSnapshot)
@@ -5467,7 +5472,7 @@ HRESULT Machine::createSharedFolder(const com::Utf8Str &aName, const com::Utf8St
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    HRESULT rc = i_checkStateDependency(MutableStateDep);
+    HRESULT rc = i_checkStateDependency(MutableOrRunningStateDep);
     if (FAILED(rc)) return rc;
 
     ComObjPtr<SharedFolder> sharedFolder;
@@ -5501,7 +5506,7 @@ HRESULT Machine::removeSharedFolder(const com::Utf8Str &aName)
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    HRESULT rc = i_checkStateDependency(MutableStateDep);
+    HRESULT rc = i_checkStateDependency(MutableOrRunningStateDep);
     if (FAILED(rc)) return rc;
 
     ComObjPtr<SharedFolder> sharedFolder;
@@ -5533,7 +5538,8 @@ HRESULT Machine::canShowConsoleWindow(BOOL *aCanShow)
                             tr("Machine is not locked for session (session state: %s)"),
                             Global::stringifySessionState(mData->mSession.mState));
 
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore calls made after #OnSessionEnd() is called */
@@ -5555,7 +5561,8 @@ HRESULT Machine::showConsoleWindow(LONG64 *aWinId)
                             tr("Machine is not locked for session (session state: %s)"),
                             Global::stringifySessionState(mData->mSession.mState));
 
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore calls made after #OnSessionEnd() is called */
@@ -5608,14 +5615,13 @@ HRESULT Machine::i_getGuestPropertyFromVM(const com::Utf8Str &aName,
     BSTR bFlags = NULL;
 
     ComPtr<IInternalSessionControl> directControl;
-    directControl = mData->mSession.mDirectControl;
-
-    /* fail if we were called after #OnSessionEnd() is called.  This is a
-     * silly race condition. */
+    {
+        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
+    }
 
-    /** @todo This code is bothering API clients (like python script clients) with
-     *        the AccessGuestProperty call, creating unncessary IPC.  Need to
-     *        have a way of figuring out which kind of direct session it is... */
+    /* ignore calls made after #OnSessionEnd() is called */
     if (!directControl)
         rc = E_ACCESSDENIED;
     else
@@ -5768,7 +5774,12 @@ HRESULT Machine::i_setGuestPropertyToVM(const com::Utf8Str &aName, const com::Ut
 
     try
     {
-        ComPtr<IInternalSessionControl> directControl = mData->mSession.mDirectControl;
+        ComPtr<IInternalSessionControl> directControl;
+        {
+            AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+            if (mData->mSession.mLockType == LockType_VM)
+                directControl = mData->mSession.mDirectControl;
+        }
 
         BSTR dummy = NULL; /* will not be changed (setter) */
         LONG64 dummy64;
@@ -5895,8 +5906,11 @@ HRESULT Machine::i_enumerateGuestPropertiesOnVM(const com::Utf8Str &aPatterns,
 {
     HRESULT rc;
     ComPtr<IInternalSessionControl> directControl;
-    directControl = mData->mSession.mDirectControl;
-
+    {
+        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
+    }
 
     com::SafeArray<BSTR> bNames;
     com::SafeArray<BSTR> bValues;
@@ -7087,6 +7101,42 @@ HRESULT Machine::cloneTo(const ComPtr<IMachine> &aTarget, CloneMode_T aMode, con
 
 }
 
+HRESULT Machine::saveState(ComPtr<IProgress> &aProgress)
+{
+    NOREF(aProgress);
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    // This check should always fail.
+    HRESULT rc = i_checkStateDependency(MutableStateDep);
+    if (FAILED(rc)) return rc;
+
+    AssertFailedReturn(E_NOTIMPL);
+}
+
+HRESULT Machine::adoptSavedState(const com::Utf8Str &aSavedStateFile)
+{
+    NOREF(aSavedStateFile);
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    // This check should always fail.
+    HRESULT rc = i_checkStateDependency(MutableStateDep);
+    if (FAILED(rc)) return rc;
+
+    AssertFailedReturn(E_NOTIMPL);
+}
+
+HRESULT Machine::discardSavedState(BOOL aFRemoveFile)
+{
+    NOREF(aFRemoveFile);
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    // This check should always fail.
+    HRESULT rc = i_checkStateDependency(MutableOrSavedStateDep);
+    if (FAILED(rc)) return rc;
+
+    AssertFailedReturn(E_NOTIMPL);
+}
+
 // public methods for internal purposes
 /////////////////////////////////////////////////////////////////////////////
 
@@ -7365,15 +7415,29 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
 
     LogFlowThisFunc(("mSession.mState=%s\n", Global::stringifySessionState(mData->mSession.mState)));
 
-    if (    mData->mSession.mState == SessionState_Locked
-         || mData->mSession.mState == SessionState_Spawning
-         || mData->mSession.mState == SessionState_Unlocking)
-        return setError(VBOX_E_INVALID_OBJECT_STATE,
-                        tr("The machine '%s' is already locked by a session (or being locked or unlocked)"),
-                        mUserData->s.strName.c_str());
+    /* The process started when launching a VM with separate UI/VM processes is always
+     * the UI process, i.e. needs special handling as it won't claim the session. */
+    bool fSeparate = strFrontend.endsWith("separate", Utf8Str::CaseInsensitive);
 
-    /* may not be busy */
-    AssertReturn(!Global::IsOnlineOrTransient(mData->mMachineState), E_FAIL);
+    if (fSeparate)
+    {
+        if (mData->mSession.mState != SessionState_Unlocked && mData->mSession.mType.compare("headless", Utf8Str::CaseInsensitive))
+            return setError(VBOX_E_INVALID_OBJECT_STATE,
+                            tr("The machine '%s' is in a state which is incompatible with launching a separate UI process"),
+                            mUserData->s.strName.c_str());
+    }
+    else
+    {
+        if (    mData->mSession.mState == SessionState_Locked
+             || mData->mSession.mState == SessionState_Spawning
+             || mData->mSession.mState == SessionState_Unlocking)
+            return setError(VBOX_E_INVALID_OBJECT_STATE,
+                            tr("The machine '%s' is already locked by a session (or being locked or unlocked)"),
+                            mUserData->s.strName.c_str());
+
+        /* may not be busy */
+        AssertReturn(!Global::IsOnlineOrTransient(mData->mMachineState), E_FAIL);
+    }
 
     /* get the path to the executable */
     char szPath[RTPATH_MAX];
@@ -7460,7 +7524,11 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
 
 
 #ifdef VBOX_WITH_QTGUI
-    if (strFrontend == "gui" || strFrontend == "GUI/Qt")
+    if (   !strFrontend.compare("gui", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("GUI/Qt", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("separate", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("gui/separate", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("GUI/Qt/separate", Utf8Str::CaseInsensitive))
     {
 # ifdef RT_OS_DARWIN /* Avoid Launch Services confusing this with the selector by using a helper app. */
         /* Modify the base path so that we don't need to use ".." below. */
@@ -7506,9 +7574,15 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
             "--comment", mUserData->s.strName.c_str(),
             "--startvm", idStr.c_str(),
             "--no-startvm-errormsgbox",
-            pszSupStartupLogArg,
+            NULL, /* For "--separate". */
+            NULL, /* For "--sup-startup-log". */
             NULL
         };
+        unsigned iArg = 6;
+        if (fSeparate)
+            apszArgs[iArg++] = "--separate";
+        apszArgs[iArg++] = pszSupStartupLogArg;
+
         vrc = RTProcCreate(szPath, apszArgs, env, 0, &pid);
     }
 #else /* !VBOX_WITH_QTGUI */
@@ -7519,7 +7593,10 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
     else
 
 #ifdef VBOX_WITH_VBOXSDL
-    if (strFrontend == "sdl" || strFrontend == "GUI/SDL")
+    if (   !strFrontend.compare("sdl", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("GUI/SDL", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("sdl/separate", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("GUI/SDL/separate", Utf8Str::CaseInsensitive))
     {
         static const char s_szVBoxSDL_exe[] = "VBoxSDL" HOSTSUFF_EXE;
         Assert(cchBufLeft >= sizeof(s_szVBoxSDL_exe));
@@ -7531,9 +7608,15 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
             szPath,
             "--comment", mUserData->s.strName.c_str(),
             "--startvm", idStr.c_str(),
-            pszSupStartupLogArg,
+            NULL, /* For "--separate". */
+            NULL, /* For "--sup-startup-log". */
             NULL
         };
+        unsigned iArg = 5;
+        if (fSeparate)
+            apszArgs[iArg++] = "--separate";
+        apszArgs[iArg++] = pszSupStartupLogArg;
+
         vrc = RTProcCreate(szPath, apszArgs, env, 0, &pid);
     }
 #else /* !VBOX_WITH_VBOXSDL */
@@ -7544,9 +7627,9 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
     else
 
 #ifdef VBOX_WITH_HEADLESS
-    if (   strFrontend == "headless"
-        || strFrontend == "capture"
-        || strFrontend == "vrdp" /* Deprecated. Same as headless. */
+    if (   !strFrontend.compare("headless", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("capture", Utf8Str::CaseInsensitive)
+        || !strFrontend.compare("vrdp", Utf8Str::CaseInsensitive) /* Deprecated. Same as headless. */
        )
     {
         /* On pre-4.0 the "headless" type was used for passing "--vrdp off" to VBoxHeadless to let it work in OSE,
@@ -7567,12 +7650,12 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
             "--comment", mUserData->s.strName.c_str(),
             "--startvm", idStr.c_str(),
             "--vrde", "config",
-            0, /* For "--capture". */
-            0, /* For "--sup-startup-log". */
-            0
+            NULL, /* For "--capture". */
+            NULL, /* For "--sup-startup-log". */
+            NULL
         };
         unsigned iArg = 7;
-        if (strFrontend == "capture")
+        if (!strFrontend.compare("capture", Utf8Str::CaseInsensitive))
             apszArgs[iArg++] = "--capture";
         apszArgs[iArg++] = pszSupStartupLogArg;
 
@@ -7603,43 +7686,53 @@ HRESULT Machine::i_launchVMProcess(IInternalSessionControl *aControl,
 
     LogFlowThisFunc(("launched.pid=%d(0x%x)\n", pid, pid));
 
-    /*
-     *  Note that we don't release the lock here before calling the client,
-     *  because it doesn't need to call us back if called with a NULL argument.
-     *  Releasing the lock here is dangerous because we didn't prepare the
-     *  launch data yet, but the client we've just started may happen to be
-     *  too fast and call LockMachine() that will fail (because of PID, etc.),
-     *  so that the Machine will never get out of the Spawning session state.
-     */
+    if (!fSeparate)
+    {
+        /*
+         *  Note that we don't release the lock here before calling the client,
+         *  because it doesn't need to call us back if called with a NULL argument.
+         *  Releasing the lock here is dangerous because we didn't prepare the
+         *  launch data yet, but the client we've just started may happen to be
+         *  too fast and call LockMachine() that will fail (because of PID, etc.),
+         *  so that the Machine will never get out of the Spawning session state.
+         */
 
-    /* inform the session that it will be a remote one */
-    LogFlowThisFunc(("Calling AssignMachine (NULL)...\n"));
+        /* inform the session that it will be a remote one */
+        LogFlowThisFunc(("Calling AssignMachine (NULL)...\n"));
 #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
-    HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, Bstr::Empty.raw());
+        HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, Bstr::Empty.raw());
 #else /* VBOX_WITH_GENERIC_SESSION_WATCHER */
-    HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, NULL);
+        HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, NULL);
 #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
-    LogFlowThisFunc(("AssignMachine (NULL) returned %08X\n", rc));
+        LogFlowThisFunc(("AssignMachine (NULL) returned %08X\n", rc));
 
-    if (FAILED(rc))
+        if (FAILED(rc))
+        {
+            /* restore the session state */
+            mData->mSession.mState = SessionState_Unlocked;
+            alock.release();
+            mParent->i_addProcessToReap(pid);
+            /* The failure may occur w/o any error info (from RPC), so provide one */
+            return setError(VBOX_E_VM_ERROR,
+                            tr("Failed to assign the machine to the session (%Rhrc)"), rc);
+        }
+
+        /* attach launch data to the machine */
+        Assert(mData->mSession.mPID == NIL_RTPROCESS);
+        mData->mSession.mRemoteControls.push_back(aControl);
+        mData->mSession.mProgress = aProgress;
+        mData->mSession.mPID = pid;
+        mData->mSession.mState = SessionState_Spawning;
+        mData->mSession.mType = strFrontend;
+    }
+    else
     {
-        /* restore the session state */
-        mData->mSession.mState = SessionState_Unlocked;
-        alock.release();
-        mParent->i_addProcessToReap(pid);
-        /* The failure may occur w/o any error info (from RPC), so provide one */
-        return setError(VBOX_E_VM_ERROR,
-                        tr("Failed to assign the machine to the session (%Rhrc)"), rc);
+        /* For separate UI process we declare the launch as completed instantly, as the
+         * actual headless VM start may or may not come. No point in remembering anything
+         * yet, as what matters for us is when the headless VM gets started. */
+        aProgress->i_notifyComplete(S_OK);
     }
 
-    /* attach launch data to the machine */
-    Assert(mData->mSession.mPID == NIL_RTPROCESS);
-    mData->mSession.mRemoteControls.push_back(aControl);
-    mData->mSession.mProgress = aProgress;
-    mData->mSession.mPID = pid;
-    mData->mSession.mState = SessionState_Spawning;
-    mData->mSession.mType = strFrontend;
-
     alock.release();
     mParent->i_addProcessToReap(pid);
 
@@ -7674,7 +7767,8 @@ bool Machine::i_isSessionOpen(ComObjPtr<SessionMachine> &aMachine,
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    if (    mData->mSession.mState == SessionState_Locked
+    if (    (   mData->mSession.mState == SessionState_Locked
+             && mData->mSession.mLockType == LockType_VM)
          || (aAllowClosing && mData->mSession.mState == SessionState_Unlocking)
        )
     {
@@ -8375,6 +8469,7 @@ HRESULT Machine::i_setMachineState(MachineState_T aMachineState)
 {
     LogFlowThisFuncEnter();
     LogFlowThisFunc(("aMachineState=%s\n", Global::stringifyMachineState(aMachineState) ));
+    Assert(aMachineState != MachineState_Null);
 
     AutoCaller autoCaller(this);
     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
@@ -10537,7 +10632,8 @@ HRESULT Machine::i_createImplicitDiffs(IProgress *aProgress,
                               &mParent->i_getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
 
     /* must be in a protective state because we release the lock below */
-    AssertReturn(   mData->mMachineState == MachineState_Saving
+    AssertReturn(   mData->mMachineState == MachineState_Snapshotting
+                 || mData->mMachineState == MachineState_OnlineSnapshotting
                  || mData->mMachineState == MachineState_LiveSnapshotting
                  || mData->mMachineState == MachineState_RestoringSnapshot
                  || mData->mMachineState == MachineState_DeletingSnapshot
@@ -10626,7 +10722,7 @@ HRESULT Machine::i_createImplicitDiffs(IProgress *aProgress,
             {
                 /* copy the attachment as is */
 
-                /** @todo the progress object created in Console::TakeSnaphot
+                /** @todo the progress object created in SessionMachine::TakeSnaphot
                  * only expects operations for hard disks. Later other
                  * device types need to show up in the progress as well. */
                 if (devType == DeviceType_HardDisk)
@@ -10788,7 +10884,8 @@ HRESULT Machine::i_deleteImplicitDiffs(bool aOnline)
 
     /* will release the lock before the potentially lengthy operation,
      * so protect with the special state (unless already protected) */
-    if (   oldState != MachineState_Saving
+    if (   oldState != MachineState_Snapshotting
+        && oldState != MachineState_OnlineSnapshotting
         && oldState != MachineState_LiveSnapshotting
         && oldState != MachineState_RestoringSnapshot
         && oldState != MachineState_DeletingSnapshot
@@ -10925,6 +11022,10 @@ HRESULT Machine::i_deleteImplicitDiffs(bool aOnline)
                                           pMedium->i_getLocationFull().c_str() ));
                 mrc = rc;
             }
+            // Clear the list of deleted implicit attachments now, while not
+            // holding the lock, as it will ultimately trigger Medium::uninit()
+            // calls which assume that the media tree lock isn't held.
+            implicitAtts.clear();
 
             alock.acquire();
 
@@ -12446,29 +12547,6 @@ void SessionMachine::uninit(Uninit::Reason aReason)
         i_rollback(false /* aNotify */);
     }
 
-    Assert(    mConsoleTaskData.strStateFilePath.isEmpty()
-            || !mConsoleTaskData.mSnapshot);
-    if (!mConsoleTaskData.strStateFilePath.isEmpty())
-    {
-        LogWarningThisFunc(("canceling failed save state request!\n"));
-        endSavingState(E_FAIL, tr("Machine terminated with pending save state!"));
-    }
-    else if (!mConsoleTaskData.mSnapshot.isNull())
-    {
-        LogWarningThisFunc(("canceling untaken snapshot!\n"));
-
-        /* delete all differencing hard disks created (this will also attach
-         * their parents back by rolling back mMediaData) */
-        i_rollbackMedia();
-
-        // delete the saved state file (it might have been already created)
-        // AFTER killing the snapshot so that releaseSavedStateFile() won't
-        // think it's still in use
-        Utf8Str strStateFile = mConsoleTaskData.mSnapshot->i_getStateFilePath();
-        mConsoleTaskData.mSnapshot->uninit();
-        i_releaseSavedStateFile(strStateFile, NULL /* pSnapshotToIgnore */ );
-    }
-
     mData->mSession.mPID = NIL_RTPROCESS;
 
     if (aReason == Uninit::Unexpected)
@@ -12569,6 +12647,7 @@ void SessionMachine::uninit(Uninit::Reason aReason)
             || aReason == Uninit::Unexpected);
 
     /* reset the rest of session data */
+    mData->mSession.mLockType = LockType_Null;
     mData->mSession.mMachine.setNull();
     mData->mSession.mState = SessionState_Unlocked;
     mData->mSession.mType.setNull();
@@ -12654,19 +12733,224 @@ HRESULT SessionMachine::reportVmStatistics(ULONG aValidStats, ULONG aCpuUser,
 #endif
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
+// SessionMachine task records
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Task record for saving the machine state.
+ */
+struct SessionMachine::SaveStateTask
+    : public Machine::Task
+{
+    SaveStateTask(SessionMachine *m,
+                  Progress *p,
+                  const Utf8Str &t,
+                  Reason_T enmReason,
+                  const Utf8Str &strStateFilePath)
+        : Task(m, p, t),
+          m_enmReason(enmReason),
+          m_strStateFilePath(strStateFilePath)
+    {}
+
+    void handler()
+    {
+        ((SessionMachine *)(Machine *)m_pMachine)->i_saveStateHandler(*this);
+    }
+
+    Reason_T m_enmReason;
+    Utf8Str m_strStateFilePath;
+};
+
+/**
+ * Task thread implementation for SessionMachine::SaveState(), called from
+ * SessionMachine::taskHandler().
+ *
+ * @note Locks this object for writing.
+ *
+ * @param task
+ * @return
+ */
+void SessionMachine::i_saveStateHandler(SaveStateTask &task)
+{
+    LogFlowThisFuncEnter();
+
+    AutoCaller autoCaller(this);
+    LogFlowThisFunc(("state=%d\n", getObjectState().getState()));
+    if (FAILED(autoCaller.rc()))
+    {
+        /* we might have been uninitialized because the session was accidentally
+         * closed by the client, so don't assert */
+        HRESULT rc = setError(E_FAIL,
+                              tr("The session has been accidentally closed"));
+        task.m_pProgress->i_notifyComplete(rc);
+        LogFlowThisFuncLeave();
+        return;
+    }
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    HRESULT rc = S_OK;
+
+    try
+    {
+        ComPtr<IInternalSessionControl> directControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
+        if (directControl.isNull())
+            throw setError(VBOX_E_INVALID_VM_STATE,
+                           tr("Trying to save state without a running VM"));
+        alock.release();
+        BOOL fSuspendedBySave;
+        rc = directControl->SaveStateWithReason(task.m_enmReason, task.m_pProgress, Bstr(task.m_strStateFilePath).raw(), task.m_machineStateBackup != MachineState_Paused, &fSuspendedBySave);
+        Assert(!fSuspendedBySave);
+        alock.acquire();
+
+        AssertStmt(   (SUCCEEDED(rc) && mData->mMachineState == MachineState_Saved)
+                   || (FAILED(rc) && mData->mMachineState == MachineState_Saving),
+                   throw E_FAIL);
+
+        if (SUCCEEDED(rc))
+        {
+            mSSData->strStateFilePath = task.m_strStateFilePath;
+
+            /* save all VM settings */
+            rc = i_saveSettings(NULL);
+                    // no need to check whether VirtualBox.xml needs saving also since
+                    // we can't have a name change pending at this point
+        }
+        else
+        {
+            // On failure, set the state to the state we had at the beginning.
+            i_setMachineState(task.m_machineStateBackup);
+            i_updateMachineStateOnClient();
+
+            // Delete the saved state file (might have been already created).
+            // No need to check whether this is shared with a snapshot here
+            // because we certainly created a fresh saved state file here.
+            RTFileDelete(task.m_strStateFilePath.c_str());
+        }
+    }
+    catch (HRESULT aRC) { rc = aRC; }
+
+    task.m_pProgress->i_notifyComplete(rc);
+
+    LogFlowThisFuncLeave();
+}
+
 /**
  *  @note Locks this object for writing.
  */
-HRESULT SessionMachine::setRemoveSavedStateFile(BOOL aRemove)
+HRESULT SessionMachine::saveState(ComPtr<IProgress> &aProgress)
+{
+    return i_saveStateWithReason(Reason_Unspecified, aProgress);
+}
+
+HRESULT SessionMachine::i_saveStateWithReason(Reason_T aReason, ComPtr<IProgress> &aProgress)
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    mRemoveSavedState = RT_BOOL(aRemove);
+    HRESULT rc = i_checkStateDependency(MutableOrRunningStateDep);
+    if (FAILED(rc)) return rc;
+
+    if (   mData->mMachineState != MachineState_Running
+        && mData->mMachineState != MachineState_Paused
+       )
+        return setError(VBOX_E_INVALID_VM_STATE,
+            tr("Cannot save the execution state as the machine is not running or paused (machine state: %s)"),
+            Global::stringifyMachineState(mData->mMachineState));
+
+    ComObjPtr<Progress> pProgress;
+    pProgress.createObject();
+    rc = pProgress->init(i_getVirtualBox(),
+                         static_cast<IMachine *>(this) /* aInitiator */,
+                         Bstr(tr("Saving the execution state of the virtual machine")).raw(),
+                         FALSE /* aCancelable */);
+    if (FAILED(rc))
+        return rc;
+
+    Utf8Str strStateFilePath;
+    i_composeSavedStateFilename(strStateFilePath);
+
+    /* create and start the task on a separate thread (note that it will not
+     * start working until we release alock) */
+    SaveStateTask *pTask = new SaveStateTask(this, pProgress, "SaveState", aReason, strStateFilePath);
+    rc = pTask->createThread();
+    if (FAILED(rc))
+        return rc;
+
+    /* set the state to Saving (expected by Session::SaveStateWithReason()) */
+    i_setMachineState(MachineState_Saving);
+    i_updateMachineStateOnClient();
+
+    pProgress.queryInterfaceTo(aProgress.asOutParam());
 
     return S_OK;
 }
 
 /**
+ *  @note Locks this object for writing.
+ */
+HRESULT SessionMachine::adoptSavedState(const com::Utf8Str &aSavedStateFile)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    HRESULT rc = i_checkStateDependency(MutableStateDep);
+    if (FAILED(rc)) return rc;
+
+    if (   mData->mMachineState != MachineState_PoweredOff
+        && mData->mMachineState != MachineState_Teleported
+        && mData->mMachineState != MachineState_Aborted
+       )
+        return setError(VBOX_E_INVALID_VM_STATE,
+            tr("Cannot adopt the saved machine state as the machine is not in Powered Off, Teleported or Aborted state (machine state: %s)"),
+            Global::stringifyMachineState(mData->mMachineState));
+
+    com::Utf8Str stateFilePathFull;
+    int vrc = i_calculateFullPath(aSavedStateFile, stateFilePathFull);
+    if (RT_FAILURE(vrc))
+        return setError(VBOX_E_FILE_ERROR,
+                        tr("Invalid saved state file path '%s' (%Rrc)"),
+                        aSavedStateFile.c_str(),
+                        vrc);
+
+    mSSData->strStateFilePath = stateFilePathFull;
+
+    /* The below i_setMachineState() will detect the state transition and will
+     * update the settings file */
+
+    return i_setMachineState(MachineState_Saved);
+}
+
+/**
+ *  @note Locks this object for writing.
+ */
+HRESULT SessionMachine::discardSavedState(BOOL aFRemoveFile)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    HRESULT rc = i_checkStateDependency(MutableOrSavedStateDep);
+    if (FAILED(rc)) return rc;
+
+    if (mData->mMachineState != MachineState_Saved)
+        return setError(VBOX_E_INVALID_VM_STATE,
+            tr("Cannot delete the machine state as the machine is not in the saved state (machine state: %s)"),
+            Global::stringifyMachineState(mData->mMachineState));
+
+    mRemoveSavedState = RT_BOOL(aFRemoveFile);
+
+    /*
+     * Saved -> PoweredOff transition will be detected in the SessionMachine
+     * and properly handled.
+     */
+    rc = i_setMachineState(MachineState_PoweredOff);
+    return rc;
+}
+
+
+/**
  *  @note Locks the same as #i_setMachineState() does.
  */
 HRESULT SessionMachine::updateState(MachineState_T aState)
@@ -13043,105 +13327,6 @@ HRESULT SessionMachine::onSessionEnd(const ComPtr<ISession> &aSession,
     return S_OK;
 }
 
-/**
- *  @note Locks this object for writing.
- */
-HRESULT SessionMachine::beginSavingState(ComPtr<IProgress> &aProgress,
-                                         com::Utf8Str &aStateFilePath)
-{
-    LogFlowThisFuncEnter();
-
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    AssertReturn(    mData->mMachineState == MachineState_Paused
-                  && mConsoleTaskData.mLastState == MachineState_Null
-                  && mConsoleTaskData.strStateFilePath.isEmpty(),
-                 E_FAIL);
-
-    /* create a progress object to track operation completion */
-    ComObjPtr<Progress> pProgress;
-    pProgress.createObject();
-    pProgress->init(i_getVirtualBox(),
-                    static_cast<IMachine *>(this) /* aInitiator */,
-                    Bstr(tr("Saving the execution state of the virtual machine")).raw(),
-                    FALSE /* aCancelable */);
-
-    /* stateFilePath is null when the machine is not running */
-    if (mData->mMachineState == MachineState_Paused)
-        i_composeSavedStateFilename(aStateFilePath);
-
-    /* fill in the console task data */
-    mConsoleTaskData.mLastState = mData->mMachineState;
-    mConsoleTaskData.strStateFilePath = aStateFilePath;
-    mConsoleTaskData.mProgress = pProgress;
-
-    /* set the state to Saving (this is expected by Console::SaveState()) */
-    i_setMachineState(MachineState_Saving);
-
-    pProgress.queryInterfaceTo(aProgress.asOutParam());
-
-    return S_OK;
-}
-
-/**
- *  @note Locks mParent + this object for writing.
- */
-HRESULT SessionMachine::endSavingState(LONG aResult,
-                                       const com::Utf8Str &aErrMsg)
-{
-    LogFlowThisFunc(("\n"));
-
-    /* endSavingState() need mParent lock */
-    AutoMultiWriteLock2 alock(mParent, this COMMA_LOCKVAL_SRC_POS);
-
-    AssertReturn(    (   (SUCCEEDED(aResult) && mData->mMachineState == MachineState_Saved)
-                      || (FAILED(aResult) && mData->mMachineState == MachineState_Saving))
-                  && mConsoleTaskData.mLastState != MachineState_Null
-                  && !mConsoleTaskData.strStateFilePath.isEmpty(),
-                 E_FAIL);
-
-    /*
-     * On failure, set the state to the state we had when BeginSavingState()
-     * was called (this is expected by Console::SaveState() and the associated
-     * task). On success the VM process already changed the state to
-     * MachineState_Saved, so no need to do anything.
-     */
-    if (FAILED(aResult))
-        i_setMachineState(mConsoleTaskData.mLastState);
-
-    return i_endSavingState(aResult, aErrMsg);
-}
-
-/**
- *  @note Locks this object for writing.
- */
-HRESULT SessionMachine::adoptSavedState(const com::Utf8Str &aSavedStateFile)
-{
-    LogFlowThisFunc(("\n"));
-
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    AssertReturn(   mData->mMachineState == MachineState_PoweredOff
-                 || mData->mMachineState == MachineState_Teleported
-                 || mData->mMachineState == MachineState_Aborted
-                 , E_FAIL); /** @todo setError. */
-
-    com::Utf8Str stateFilePathFull;
-    int vrc = i_calculateFullPath(aSavedStateFile, stateFilePathFull);
-    if (RT_FAILURE(vrc))
-        return setError(VBOX_E_FILE_ERROR,
-                        tr("Invalid saved state file path '%s' (%Rrc)"),
-                        aSavedStateFile.c_str(),
-                        vrc);
-
-    mSSData->strStateFilePath = stateFilePathFull;
-
-    /* The below i_setMachineState() will detect the state transition and will
-     * update the settings file */
-
-    return i_setMachineState(MachineState_Saved);
-}
-
 HRESULT SessionMachine::pullGuestProperties(std::vector<com::Utf8Str> &aNames,
                                             std::vector<com::Utf8Str> &aValues,
                                             std::vector<LONG64>       &aTimestamps,
@@ -13219,6 +13404,7 @@ HRESULT SessionMachine::pushGuestProperty(const  com::Utf8Str &aName,
             case MachineState_Running:
             case MachineState_Teleporting:
             case MachineState_TeleportingPausedVM:
+            case MachineState_OnlineSnapshotting:
             case MachineState_LiveSnapshotting:
             case MachineState_DeletingSnapshotOnline:
             case MachineState_DeletingSnapshotPaused:
@@ -13492,7 +13678,8 @@ HRESULT SessionMachine::i_onNetworkAdapterChange(INetworkAdapter *networkAdapter
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13517,7 +13704,8 @@ HRESULT SessionMachine::i_onNATRedirectRuleChange(ULONG ulSlot, BOOL aNatRuleRem
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13545,7 +13733,8 @@ HRESULT SessionMachine::i_onSerialPortChange(ISerialPort *serialPort)
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13568,7 +13757,8 @@ HRESULT SessionMachine::i_onParallelPortChange(IParallelPort *parallelPort)
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13591,7 +13781,8 @@ HRESULT SessionMachine::i_onStorageControllerChange()
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13614,7 +13805,8 @@ HRESULT SessionMachine::i_onMediumChange(IMediumAttachment *aAttachment, BOOL aF
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13637,7 +13829,8 @@ HRESULT SessionMachine::i_onCPUChange(ULONG aCPU, BOOL aRemove)
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13657,7 +13850,8 @@ HRESULT SessionMachine::i_onCPUExecutionCapChange(ULONG aExecutionCap)
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13680,7 +13874,8 @@ HRESULT SessionMachine::i_onVRDEServerChange(BOOL aRestart)
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13703,7 +13898,8 @@ HRESULT SessionMachine::i_onVideoCaptureChange()
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13726,7 +13922,8 @@ HRESULT SessionMachine::i_onUSBControllerChange()
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13749,7 +13946,8 @@ HRESULT SessionMachine::i_onSharedFolderChange()
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13772,7 +13970,8 @@ HRESULT SessionMachine::i_onClipboardModeChange(ClipboardMode_T aClipboardMode)
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13795,7 +13994,8 @@ HRESULT SessionMachine::i_onDnDModeChange(DnDMode_T aDnDMode)
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13818,7 +14018,8 @@ HRESULT SessionMachine::i_onBandwidthGroupChange(IBandwidthGroup *aBandwidthGrou
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13841,7 +14042,8 @@ HRESULT SessionMachine::i_onStorageDeviceChange(IMediumAttachment *aAttachment,
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* ignore notifications sent after #OnSessionEnd() is called */
@@ -13907,7 +14109,8 @@ HRESULT SessionMachine::i_onUSBDeviceAttach(IUSBDevice *aDevice,
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* fail on notifications sent after #OnSessionEnd() is called, it is
@@ -13939,7 +14142,8 @@ HRESULT SessionMachine::i_onUSBDeviceDetach(IN_BSTR aId,
     ComPtr<IInternalSessionControl> directControl;
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
     }
 
     /* fail on notifications sent after #OnSessionEnd() is called, it is
@@ -13958,68 +14162,6 @@ HRESULT SessionMachine::i_onUSBDeviceDetach(IN_BSTR aId,
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- *  Helper method to finalize saving the state.
- *
- *  @note Must be called from under this object's lock.
- *
- *  @param aRc      S_OK if the snapshot has been taken successfully
- *  @param aErrMsg  human readable error message for failure
- *
- *  @note Locks mParent + this objects for writing.
- */
-HRESULT SessionMachine::i_endSavingState(HRESULT aRc, const Utf8Str &aErrMsg)
-{
-    LogFlowThisFuncEnter();
-
-    AutoCaller autoCaller(this);
-    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
-
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    HRESULT rc = S_OK;
-
-    if (SUCCEEDED(aRc))
-    {
-        mSSData->strStateFilePath = mConsoleTaskData.strStateFilePath;
-
-        /* save all VM settings */
-        rc = i_saveSettings(NULL);
-                // no need to check whether VirtualBox.xml needs saving also since
-                // we can't have a name change pending at this point
-    }
-    else
-    {
-        // delete the saved state file (it might have been already created);
-        // we need not check whether this is shared with a snapshot here because
-        // we certainly created this saved state file here anew
-        RTFileDelete(mConsoleTaskData.strStateFilePath.c_str());
-    }
-
-    /* notify the progress object about operation completion */
-    Assert(mConsoleTaskData.mProgress);
-    if (SUCCEEDED(aRc))
-        mConsoleTaskData.mProgress->i_notifyComplete(S_OK);
-    else
-    {
-        if (aErrMsg.length())
-            mConsoleTaskData.mProgress->i_notifyComplete(aRc,
-                                                         COM_IIDOF(ISession),
-                                                         getComponentName(),
-                                                         aErrMsg.c_str());
-        else
-            mConsoleTaskData.mProgress->i_notifyComplete(aRc);
-    }
-
-    /* clear out the temporary saved state data */
-    mConsoleTaskData.mLastState = MachineState_Null;
-    mConsoleTaskData.strStateFilePath.setNull();
-    mConsoleTaskData.mProgress.setNull();
-
-    LogFlowThisFuncLeave();
-    return rc;
-}
-
-/**
  * Deletes the given file if it is no longer in use by either the current machine state
  * (if the machine is "saved") or any of the machine's snapshots.
  *
@@ -14215,6 +14357,7 @@ HRESULT SessionMachine::i_setMachineState(MachineState_T aMachineState)
     else if (   (   oldMachineState == MachineState_Running
                  || oldMachineState == MachineState_Paused
                  || oldMachineState == MachineState_Teleporting
+                 || oldMachineState == MachineState_OnlineSnapshotting
                  || oldMachineState == MachineState_LiveSnapshotting
                  || oldMachineState == MachineState_Stuck
                  || oldMachineState == MachineState_Starting
@@ -14229,11 +14372,6 @@ HRESULT SessionMachine::i_setMachineState(MachineState_T aMachineState)
                  || aMachineState == MachineState_Teleported
                  || aMachineState == MachineState_Aborted
                 )
-             /* ignore PoweredOff->Saving->PoweredOff transition when taking a
-              * snapshot */
-             && (   mConsoleTaskData.mSnapshot.isNull()
-                 || mConsoleTaskData.mLastState >= MachineState_Running /** @todo Live Migration: clean up (lazy bird) */
-                )
             )
     {
         /* The EMT thread has just stopped, unlock attached media. Note that as
@@ -14266,7 +14404,7 @@ HRESULT SessionMachine::i_setMachineState(MachineState_T aMachineState)
             )
     {
         /*
-         *  delete the saved state after Console::ForgetSavedState() is called
+         *  delete the saved state after SessionMachine::ForgetSavedState() is called
          *  or if the VM process (owning a direct VM session) crashed while the
          *  VM was Saved
          */
@@ -14412,7 +14550,8 @@ HRESULT SessionMachine::i_updateMachineStateOnClient()
     {
         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
         AssertReturn(!!mData, E_FAIL);
-        directControl = mData->mSession.mDirectControl;
+        if (mData->mSession.mLockType == LockType_VM)
+            directControl = mData->mSession.mDirectControl;
 
         /* directControl may be already set to NULL here in #OnSessionEnd()
          * called too early by the direct session process while there is still
@@ -14425,19 +14564,50 @@ HRESULT SessionMachine::i_updateMachineStateOnClient()
 
         if (mData->mSession.mState == SessionState_Unlocking)
             return S_OK;
-
-        AssertReturn(!directControl.isNull(), E_FAIL);
     }
 
+    /* ignore notifications sent after #OnSessionEnd() is called */
+    if (!directControl)
+        return S_OK;
+
     return directControl->UpdateMachineState(mData->mMachineState);
 }
 
-HRESULT Machine::setRemoveSavedStateFile(BOOL aRemove)
+
+/**
+ * Static Machine method that can get passed to RTThreadCreate to
+ * have a thread started for a Task. See Machine::Task.
+ */
+/* static */ DECLCALLBACK(int) Machine::taskHandler(RTTHREAD /* thread */, void *pvUser)
 {
-    NOREF(aRemove);
-    ReturnComNotImplemented();
+    AssertReturn(pvUser, VERR_INVALID_POINTER);
+
+    Task *pTask = static_cast<Task *>(pvUser);
+    pTask->handler();
+    /** @todo r=klaus it would be safer to update the progress object here,
+     * as it avoids possible races due to scoping issues/tricks in the handler */
+    // it's our responsibility to delete the task
+    delete pTask;
+
+    return 0;
+}
+
+/*static*/
+HRESULT Machine::i_setErrorStatic(HRESULT aResultCode, const char *pcszMsg, ...)
+{
+    va_list args;
+    va_start(args, pcszMsg);
+    HRESULT rc = setErrorInternal(aResultCode,
+                                  getStaticClassIID(),
+                                  getStaticComponentName(),
+                                  Utf8Str(pcszMsg, args),
+                                  false /* aWarning */,
+                                  true /* aLogIt */);
+    va_end(args);
+    return rc;
 }
 
+
 HRESULT Machine::updateState(MachineState_T aState)
 {
     NOREF(aState);
@@ -14514,83 +14684,11 @@ HRESULT Machine::onSessionEnd(const ComPtr<ISession> &aSession,
     ReturnComNotImplemented();
 }
 
-HRESULT Machine::beginSavingState(ComPtr<IProgress> &aProgress,
-                                  com::Utf8Str &aStateFilePath)
-{
-    NOREF(aProgress);
-    NOREF(aStateFilePath);
-    ReturnComNotImplemented();
-}
-
-HRESULT Machine::endSavingState(LONG aResult,
-                                const com::Utf8Str &aErrMsg)
-{
-    NOREF(aResult);
-    NOREF(aErrMsg);
-    ReturnComNotImplemented();
-}
-
-HRESULT Machine::adoptSavedState(const com::Utf8Str &aSavedStateFile)
-{
-    NOREF(aSavedStateFile);
-    ReturnComNotImplemented();
-}
-
-HRESULT Machine::beginTakingSnapshot(const ComPtr<IConsole> &aInitiator,
-                                     const com::Utf8Str &aName,
-                                     const com::Utf8Str &aDescription,
-                                     const ComPtr<IProgress> &aConsoleProgress,
-                                     BOOL aFTakingSnapshotOnline,
-                                     com::Utf8Str &aStateFilePath)
-{
-    NOREF(aInitiator);
-    NOREF(aName);
-    NOREF(aDescription);
-    NOREF(aConsoleProgress);
-    NOREF(aFTakingSnapshotOnline);
-    NOREF(aStateFilePath);
-    ReturnComNotImplemented();
-}
-
-HRESULT Machine::endTakingSnapshot(BOOL aSuccess)
-{
-    NOREF(aSuccess);
-    ReturnComNotImplemented();
-}
-
-HRESULT Machine::deleteSnapshot(const ComPtr<IConsole> &aInitiator,
-                                const com::Guid &aStartId,
-                                const com::Guid &aEndId,
-                                BOOL aDeleteAllChildren,
-                                MachineState_T *aMachineState,
-                                ComPtr<IProgress> &aProgress)
-{
-    NOREF(aInitiator);
-    NOREF(aStartId);
-    NOREF(aEndId);
-    NOREF(aDeleteAllChildren);
-    NOREF(aMachineState);
-    NOREF(aProgress);
-    ReturnComNotImplemented();
-}
-
 HRESULT Machine::finishOnlineMergeMedium()
 {
     ReturnComNotImplemented();
 }
 
-HRESULT Machine::restoreSnapshot(const ComPtr<IConsole> &aInitiator,
-                                 const ComPtr<ISnapshot> &aSnapshot,
-                                 MachineState_T *aMachineState,
-                                 ComPtr<IProgress> &aProgress)
-{
-    NOREF(aInitiator);
-    NOREF(aSnapshot);
-    NOREF(aMachineState);
-    NOREF(aProgress);
-    ReturnComNotImplemented();
-}
-
 HRESULT Machine::pullGuestProperties(std::vector<com::Utf8Str> &aNames,
                                      std::vector<com::Utf8Str> &aValues,
                                      std::vector<LONG64> &aTimestamps,
diff --git a/src/VBox/Main/src-server/MediumImpl.cpp b/src/VBox/Main/src-server/MediumImpl.cpp
index 37a766f..acf54a1 100644
--- a/src/VBox/Main/src-server/MediumImpl.cpp
+++ b/src/VBox/Main/src-server/MediumImpl.cpp
@@ -571,6 +571,7 @@ public:
                const char *aFilename,
                MediumFormat *aFormat,
                MediumVariant_T aVariant,
+               SecretKeyStore *pSecretKeyStore,
                VDINTERFACEIO *aVDImageIOIf,
                void *aVDImageIOUser,
                MediumLockList *aSourceMediumLockList,
@@ -580,6 +581,7 @@ public:
           mFilename(aFilename),
           mFormat(aFormat),
           mVariant(aVariant),
+          m_pSecretKeyStore(pSecretKeyStore),
           mfKeepSourceMediumLockList(fKeepSourceMediumLockList)
     {
         AssertReturnVoidStmt(aSourceMediumLockList != NULL, mRC = E_FAIL);
@@ -605,6 +607,7 @@ public:
     ComObjPtr<MediumFormat> mFormat;
     MediumVariant_T mVariant;
     PVDINTERFACE mVDImageIfaces;
+    SecretKeyStore *m_pSecretKeyStore;
 
 private:
     virtual HRESULT handler();
@@ -5586,6 +5589,8 @@ HRESULT Medium::i_fixParentUuidOfChildren(MediumLockList *pChildrenToReparent)
  * @param aFormat               Medium format for creating @a aFilename.
  * @param aVariant              Which exact image format variant to use
  *                              for the destination image.
+ * @param pKeyStore             The optional key store for decrypting the data
+ *                              for encrypted media during the export.
  * @param aVDImageIOCallbacks   Pointer to the callback table for a
  *                              VDINTERFACEIO interface. May be NULL.
  * @param aVDImageIOUser        Opaque data for the callbacks.
@@ -5596,6 +5601,7 @@ HRESULT Medium::i_fixParentUuidOfChildren(MediumLockList *pChildrenToReparent)
 HRESULT Medium::i_exportFile(const char *aFilename,
                              const ComObjPtr<MediumFormat> &aFormat,
                              MediumVariant_T aVariant,
+                             SecretKeyStore *pKeyStore,
                              PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser,
                              const ComObjPtr<Progress> &aProgress)
 {
@@ -5637,7 +5643,7 @@ HRESULT Medium::i_exportFile(const char *aFilename,
 
         /* setup task object to carry out the operation asynchronously */
         pTask = new Medium::ExportTask(this, aProgress, aFilename, aFormat,
-                                       aVariant, aVDImageIOIf,
+                                       aVariant, pKeyStore, aVDImageIOIf,
                                        aVDImageIOUser, pSourceMediumLockList);
         rc = pTask->rc();
         AssertComRC(rc);
@@ -5899,6 +5905,24 @@ HRESULT Medium::i_cloneToEx(const ComObjPtr<Medium> &aTarget, ULONG aVariant,
     return rc;
 }
 
+/**
+ * Returns the key identifier for this medium if encryption is configured.
+ *
+ * @returns Key identifier or empty string if no encryption is configured.
+ */
+const Utf8Str& Medium::i_getKeyId()
+{
+    ComObjPtr<Medium> pBase = i_getBase();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    settings::StringsMap::const_iterator it = pBase->m->mapProperties.find("CRYPT/KeyId");
+    if (it == pBase->m->mapProperties.end())
+        return Utf8Str::Empty;
+
+    return it->second;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 // Private methods
@@ -8727,6 +8751,7 @@ HRESULT Medium::i_taskExportHandler(Medium::ExportTask &task)
         /* Lock all in {parent,child} order. The lock is also used as a
          * signal from the task initiator (which releases it only after
          * RTThreadCreate()) that we can start the job. */
+        ComObjPtr<Medium> pBase = i_getBase();
         AutoWriteLock thisLock(this COMMA_LOCKVAL_SRC_POS);
 
         PVBOXHDD hdd;
@@ -8735,6 +8760,81 @@ HRESULT Medium::i_taskExportHandler(Medium::ExportTask &task)
 
         try
         {
+            settings::StringsMap::iterator itKeyStore = pBase->m->mapProperties.find("CRYPT/KeyStore");
+            if (itKeyStore != pBase->m->mapProperties.end())
+            {
+                settings::StringsMap::iterator itKeyId = pBase->m->mapProperties.find("CRYPT/KeyId");
+
+#ifdef VBOX_WITH_EXTPACK
+                static const Utf8Str strExtPackPuel("Oracle VM VirtualBox Extension Pack");
+                static const char *s_pszVDPlugin = "VDPluginCrypt";
+                ExtPackManager *pExtPackManager = m->pVirtualBox->i_getExtPackManager();
+                if (pExtPackManager->i_isExtPackUsable(strExtPackPuel.c_str()))
+                {
+                    /* Load the plugin */
+                    Utf8Str strPlugin;
+                    rc = pExtPackManager->i_getLibraryPathForExtPack(s_pszVDPlugin, &strExtPackPuel, &strPlugin);
+                    if (SUCCEEDED(rc))
+                    {
+                        vrc = VDPluginLoadFromFilename(strPlugin.c_str());
+                        if (RT_FAILURE(vrc))
+                            throw setError(VBOX_E_NOT_SUPPORTED,
+                                           tr("Retrieving encryption settings of the image failed because the encryption plugin could not be loaded (%s)"),
+                                           i_vdError(vrc).c_str());
+                    }
+                    else
+                        throw setError(VBOX_E_NOT_SUPPORTED,
+                                       tr("Encryption is not supported because the extension pack '%s' is missing the encryption plugin (old extension pack installed?)"),
+                                       strExtPackPuel.c_str());
+                }
+                else
+                    throw setError(VBOX_E_NOT_SUPPORTED,
+                                   tr("Encryption is not supported because the extension pack '%s' is missing"),
+                                   strExtPackPuel.c_str());
+#else
+                throw setError(VBOX_E_NOT_SUPPORTED,
+                               tr("Encryption is not supported because extension pack support is not built in"));
+#endif
+
+                if (itKeyId == pBase->m->mapProperties.end())
+                    throw setError(VBOX_E_INVALID_OBJECT_STATE,
+                                   tr("Image '%s' is configured for encryption but doesn't has a key identifier set"),
+                                   pBase->m->strLocationFull.c_str());
+
+                /* Find the proper secret key in the key store. */
+                if (!task.m_pSecretKeyStore)
+                    throw setError(VBOX_E_INVALID_OBJECT_STATE,
+                                   tr("Image '%s' is configured for encryption but there is no key store to retrieve the password from"),
+                                   pBase->m->strLocationFull.c_str());
+
+                SecretKey *pKey = NULL;
+                vrc = task.m_pSecretKeyStore->retainSecretKey(itKeyId->second, &pKey);
+                if (RT_FAILURE(vrc))
+                    throw setError(VBOX_E_INVALID_OBJECT_STATE,
+                                   tr("Failed to retrieve the secret key with ID \"%s\" from the store (%Rrc)"),
+                                   itKeyId->second.c_str(), vrc);
+
+                Medium::CryptoFilterSettings CryptoSettingsRead;
+                i_taskEncryptSettingsSetup(&CryptoSettingsRead, NULL, itKeyStore->second.c_str(), (const char *)pKey->getKeyBuffer(),
+                                           false /* fCreateKeyStore */);
+                vrc = VDFilterAdd(hdd, "CRYPT", VD_FILTER_FLAGS_READ, CryptoSettingsRead.vdFilterIfaces);
+                if (vrc == VERR_VD_PASSWORD_INCORRECT)
+                {
+                    task.m_pSecretKeyStore->releaseSecretKey(itKeyId->second);
+                    throw setError(VBOX_E_PASSWORD_INCORRECT,
+                                   tr("The password to decrypt the image is incorrect"));
+                }
+                else if (RT_FAILURE(vrc))
+                {
+                    task.m_pSecretKeyStore->releaseSecretKey(itKeyId->second);
+                    throw setError(VBOX_E_INVALID_OBJECT_STATE,
+                                   tr("Failed to load the decryption filter: %s"),
+                                   i_vdError(vrc).c_str());
+                }
+
+                task.m_pSecretKeyStore->releaseSecretKey(itKeyId->second);
+            }
+
             /* Open all media in the source chain. */
             MediumLockList::Base::const_iterator sourceListBegin =
                 task.mpSourceMediumLockList->GetBegin();
diff --git a/src/VBox/Main/src-server/Performance.cpp b/src/VBox/Main/src-server/Performance.cpp
index db87456..443e65b 100644
--- a/src/VBox/Main/src-server/Performance.cpp
+++ b/src/VBox/Main/src-server/Performance.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2008-2014 Oracle Corporation
+ * Copyright (C) 2008-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -310,7 +310,7 @@ HRESULT CollectorGuest::enableInternal(ULONG mask)
             return ret;
 
         /* get the associated console; this is a remote call (!) */
-        ret = directControl->GetRemoteConsole(mConsole.asOutParam());
+        ret = directControl->COMGETTER(RemoteConsole)(mConsole.asOutParam());
         if (ret != S_OK)
             return ret;
 
diff --git a/src/VBox/Main/src-server/SerialPortImpl.cpp b/src/VBox/Main/src-server/SerialPortImpl.cpp
index 42cb9b9..29d5c4c 100644
--- a/src/VBox/Main/src-server/SerialPortImpl.cpp
+++ b/src/VBox/Main/src-server/SerialPortImpl.cpp
@@ -257,6 +257,13 @@ HRESULT SerialPort::setHostMode(PortMode_T aHostMode)
                                        "because the device path is empty or null"),
                                     m->bd->ulSlot);
                 break;
+            case PortMode_TCP:
+                if (m->bd->strPath.isEmpty())
+                    return setError(E_INVALIDARG,
+                                    tr("Cannot set the host device mode of the serial port %d "
+                                       "because the server address or TCP port is invalid"),
+                                    m->bd->ulSlot);
+                break;
             case PortMode_Disconnected:
                 break;
         }
@@ -636,12 +643,13 @@ HRESULT SerialPort::i_checkSetPath(const Utf8Str &str)
 
     if (    (    m->bd->portMode == PortMode_HostDevice
               || m->bd->portMode == PortMode_HostPipe
+              || m->bd->portMode == PortMode_TCP
               || m->bd->portMode == PortMode_RawFile
             ) && str.isEmpty()
        )
         return setError(E_INVALIDARG,
                         tr("Path of the serial port %d may not be empty or null in "
-                           "host pipe or host device mode"),
+                           "host pipe, host device or TCP mode"),
                         m->bd->ulSlot);
 
     return S_OK;
diff --git a/src/VBox/Main/src-server/SnapshotImpl.cpp b/src/VBox/Main/src-server/SnapshotImpl.cpp
index 4c9a2ba..a52956b 100644
--- a/src/VBox/Main/src-server/SnapshotImpl.cpp
+++ b/src/VBox/Main/src-server/SnapshotImpl.cpp
@@ -411,7 +411,7 @@ HRESULT Snapshot::getChildren(std::vector<ComPtr<ISnapshot> > &aChildren)
     return S_OK;
 }
 
-HRESULT Snapshot::getChildrenCount(ULONG* count)
+HRESULT Snapshot::getChildrenCount(ULONG *count)
 {
     *count = i_getChildrenCount();
 
@@ -1304,50 +1304,75 @@ HRESULT SnapshotMachine::i_onSnapshotChange(Snapshot *aSnapshot)
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
- * Abstract base class for SessionMachine::RestoreSnapshotTask and
- * SessionMachine::DeleteSnapshotTask. This is necessary since
- * RTThreadCreate cannot call a method as its thread function, so
- * instead we have it call the static SessionMachine::taskHandler,
- * which can then call the handler() method in here (implemented
- * by the children).
+ * Still abstract base class for SessionMachine::TakeSnapshotTask,
+ * SessionMachine::RestoreSnapshotTask and SessionMachine::DeleteSnapshotTask.
  */
 struct SessionMachine::SnapshotTask
+    : public SessionMachine::Task
 {
     SnapshotTask(SessionMachine *m,
                  Progress *p,
+                 const Utf8Str &t,
                  Snapshot *s)
-        : pMachine(m),
-          pProgress(p),
-          machineStateBackup(m->mData->mMachineState), // save the current machine state
-          pSnapshot(s)
+        : Task(m, p, t),
+          m_pSnapshot(s)
     {}
 
-    void modifyBackedUpState(MachineState_T s)
-    {
-        *const_cast<MachineState_T*>(&machineStateBackup) = s;
+    ComObjPtr<Snapshot> m_pSnapshot;
+};
+
+/** Take snapshot task */
+struct SessionMachine::TakeSnapshotTask
+    : public SessionMachine::SnapshotTask
+{
+    TakeSnapshotTask(SessionMachine *m,
+                     Progress *p,
+                     const Utf8Str &t,
+                     Snapshot *s,
+                     const Utf8Str &strName,
+                     const Utf8Str &strDescription,
+                     bool fPause,
+                     uint32_t uMemSize,
+                     bool fTakingSnapshotOnline)
+        : SnapshotTask(m, p, t, s),
+          m_strName(strName),
+          m_strDescription(strDescription),
+          m_fPause(fPause),
+          m_uMemSize(uMemSize),
+          m_fTakingSnapshotOnline(fTakingSnapshotOnline)
+    {
+        if (fTakingSnapshotOnline)
+            m_pDirectControl = m->mData->mSession.mDirectControl;
     }
 
-    virtual void handler() = 0;
+    void handler()
+    {
+        ((SessionMachine *)(Machine *)m_pMachine)->i_takeSnapshotHandler(*this);
+    }
 
-    ComObjPtr<SessionMachine>       pMachine;
-    ComObjPtr<Progress>             pProgress;
-    const MachineState_T            machineStateBackup;
-    ComObjPtr<Snapshot>             pSnapshot;
+    Utf8Str m_strName;
+    Utf8Str m_strDescription;
+    Utf8Str m_strStateFilePath;
+    ComPtr<IInternalSessionControl> m_pDirectControl;
+    bool m_fPause;
+    uint32_t m_uMemSize;
+    bool m_fTakingSnapshotOnline;
 };
 
-/** Restore snapshot state task */
+/** Restore snapshot task */
 struct SessionMachine::RestoreSnapshotTask
     : public SessionMachine::SnapshotTask
 {
     RestoreSnapshotTask(SessionMachine *m,
                         Progress *p,
+                        const Utf8Str &t,
                         Snapshot *s)
-        : SnapshotTask(m, p, s)
+        : SnapshotTask(m, p, t, s)
     {}
 
     void handler()
     {
-        pMachine->i_restoreSnapshotHandler(*this);
+        ((SessionMachine *)(Machine *)m_pMachine)->i_restoreSnapshotHandler(*this);
     }
 };
 
@@ -1357,230 +1382,443 @@ struct SessionMachine::DeleteSnapshotTask
 {
     DeleteSnapshotTask(SessionMachine *m,
                        Progress *p,
+                       const Utf8Str &t,
                        bool fDeleteOnline,
                        Snapshot *s)
-        : SnapshotTask(m, p, s),
+        : SnapshotTask(m, p, t, s),
           m_fDeleteOnline(fDeleteOnline)
     {}
 
     void handler()
     {
-        pMachine->i_deleteSnapshotHandler(*this);
+        ((SessionMachine *)(Machine *)m_pMachine)->i_deleteSnapshotHandler(*this);
     }
 
     bool m_fDeleteOnline;
 };
 
-/**
- * Static SessionMachine method that can get passed to RTThreadCreate to
- * have a thread started for a SnapshotTask. See SnapshotTask above.
- *
- * This calls either RestoreSnapshotTask::handler() or DeleteSnapshotTask::handler().
- */
-
-/* static */ DECLCALLBACK(int) SessionMachine::taskHandler(RTTHREAD /* thread */, void *pvUser)
-{
-    AssertReturn(pvUser, VERR_INVALID_POINTER);
-
-    SnapshotTask *task = static_cast<SnapshotTask*>(pvUser);
-    task->handler();
-
-    // it's our responsibility to delete the task
-    delete task;
-
-    return 0;
-}
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-// TakeSnapshot methods (SessionMachine and related tasks)
+// TakeSnapshot methods (Machine and related tasks)
 //
 ////////////////////////////////////////////////////////////////////////////////
 
-/**
- * Implementation for IInternalMachineControl::beginTakingSnapshot().
- *
- * Gets called indirectly from Console::TakeSnapshot, which creates a
- * progress object in the client and then starts a thread
- * (Console::fntTakeSnapshotWorker) which then calls this.
- *
- * In other words, the asynchronous work for taking snapshots takes place
- * on the _client_ (in the Console). This is different from restoring
- * or deleting snapshots, which start threads on the server.
- *
- * This does the server-side work of taking a snapshot: it creates differencing
- * images for all hard disks attached to the machine and then creates a
- * Snapshot object with a corresponding SnapshotMachine to save the VM settings.
- *
- * The client's fntTakeSnapshotWorker() blocks while this takes place.
- * After this returns successfully, fntTakeSnapshotWorker() will begin
- * saving the machine state to the snapshot object and reconfigure the
- * hard disks.
- *
- * When the console is done, it calls SessionMachine::EndTakingSnapshot().
- *
- * @note Locks mParent + this object for writing.
- *
- * @param aInitiator in: The console on which Console::TakeSnapshot was called.
- * @param aName  in: The name for the new snapshot.
- * @param aDescription  in: A description for the new snapshot.
- * @param aConsoleProgress  in: The console's (client's) progress object.
- * @param fTakingSnapshotOnline  in: True if an online snapshot is being taken (i.e. machine is running).
- * @param aStateFilePath out: name of file in snapshots folder to which the console should write the VM state.
- * @return
- */
-HRESULT SessionMachine::beginTakingSnapshot(const ComPtr<IConsole> &aInitiator,
-                                            const com::Utf8Str &aName,
-                                            const com::Utf8Str &aDescription,
-                                            const ComPtr<IProgress> &aConsoleProgress,
-                                            BOOL  aFTakingSnapshotOnline,
-                                            com::Utf8Str &aStateFilePath)
-{
-    NOREF(aInitiator);
-    LogFlowThisFuncEnter();
-
-    LogFlowThisFunc(("aName='%s' aFTakingSnapshotOnline=%RTbool\n", aName.c_str(), aFTakingSnapshotOnline));
+HRESULT Machine::takeSnapshot(const com::Utf8Str &aName,
+                              const com::Utf8Str &aDescription,
+                              BOOL fPause,
+                              ComPtr<IProgress> &aProgress)
+{
+    NOREF(aName);
+    NOREF(aDescription);
+    NOREF(fPause);
+    NOREF(aProgress);
+    ReturnComNotImplemented();
+}
 
+HRESULT SessionMachine::takeSnapshot(const com::Utf8Str &aName,
+                                     const com::Utf8Str &aDescription,
+                                     BOOL fPause,
+                                     ComPtr<IProgress> &aProgress)
+{
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+    LogFlowThisFunc(("aName='%s' mMachineState=%d\n", aName.c_str(), mData->mMachineState));
+
+    if (Global::IsTransient(mData->mMachineState))
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Cannot take a snapshot of the machine while it is changing the state (machine state: %s)"),
+                        Global::stringifyMachineState(mData->mMachineState));
 
-    AssertReturn(    !Global::IsOnlineOrTransient(mData->mMachineState)
-                  || mData->mMachineState == MachineState_Running
-                  || mData->mMachineState == MachineState_Paused, E_FAIL);
-    AssertReturn(mConsoleTaskData.mLastState == MachineState_Null, E_FAIL);
-    AssertReturn(mConsoleTaskData.mSnapshot.isNull(), E_FAIL);
+    HRESULT rc = i_checkStateDependency(MutableOrSavedOrRunningStateDep);
+    if (FAILED(rc))
+        return rc;
 
-    if (   mData->mCurrentSnapshot
-        && mData->mCurrentSnapshot->i_getDepth() >= SETTINGS_SNAPSHOT_DEPTH_MAX)
+    // prepare the progress object:
+    // a) count the no. of hard disk attachments to get a matching no. of progress sub-operations
+    ULONG cOperations = 2;              // always at least setting up + finishing up
+    ULONG ulTotalOperationsWeight = 2;  // one each for setting up + finishing up
+
+    for (MediaData::AttachmentList::iterator it = mMediaData->mAttachments.begin();
+         it != mMediaData->mAttachments.end();
+         ++it)
     {
+        const ComObjPtr<MediumAttachment> pAtt(*it);
+        AutoReadLock attlock(pAtt COMMA_LOCKVAL_SRC_POS);
+        AutoCaller attCaller(pAtt);
+        if (pAtt->i_getType() == DeviceType_HardDisk)
+        {
+            ++cOperations;
 
-        return setError(VBOX_E_INVALID_OBJECT_STATE,
-                        tr("Cannot take another snapshot for machine '%s', because it exceeds the maximum snapshot depth limit. Please delete some earlier snapshot which you no longer need"),
-                        mUserData->s.strName.c_str());
+            // assume that creating a diff image takes as long as saving a 1MB state
+            ulTotalOperationsWeight += 1;
+        }
     }
 
-    if (    !aFTakingSnapshotOnline
-         && mData->mMachineState != MachineState_Saved
-       )
+    // b) one extra sub-operations for online snapshots OR offline snapshots that have a saved state (needs to be copied)
+    const bool fTakingSnapshotOnline = Global::IsOnline(mData->mMachineState);
+    LogFlowThisFunc(("fTakingSnapshotOnline = %d\n", fTakingSnapshotOnline));
+    if (fTakingSnapshotOnline)
     {
-        /* save all current settings to ensure current changes are committed and
-         * hard disks are fixed up */
-        HRESULT rc = i_saveSettings(NULL);
-                // no need to check for whether VirtualBox.xml needs changing since
-                // we can't have a machine XML rename pending at this point
-        if (FAILED(rc)) return rc;
+        ++cOperations;
+        ulTotalOperationsWeight += mHWData->mMemorySize;
     }
 
-    /* create an ID for the snapshot */
-    Guid snapshotId;
-    snapshotId.create();
+    // finally, create the progress object
+    ComObjPtr<Progress> pProgress;
+    pProgress.createObject();
+    rc = pProgress->init(mParent,
+                         static_cast<IMachine *>(this),
+                         Bstr(tr("Taking a snapshot of the virtual machine")).raw(),
+                         fTakingSnapshotOnline /* aCancelable */,
+                         cOperations,
+                         ulTotalOperationsWeight,
+                         Bstr(tr("Setting up snapshot operation")).raw(),      // first sub-op description
+                         1);        // ulFirstOperationWeight
+    if (FAILED(rc))
+        return rc;
 
-    /* stateFilePath is null when the machine is not online nor saved */
-    if (aFTakingSnapshotOnline)
+    /* create and start the task on a separate thread (note that it will not
+     * start working until we release alock) */
+    TakeSnapshotTask *pTask = new TakeSnapshotTask(this,
+                                                   pProgress,
+                                                   "TakeSnap",
+                                                   NULL /* pSnapshot */,
+                                                   aName,
+                                                   aDescription,
+                                                   !!fPause,
+                                                   mHWData->mMemorySize,
+                                                   fTakingSnapshotOnline);
+    rc = pTask->createThread();
+    if (FAILED(rc))
+        return rc;
+
+    /* set the proper machine state (note: after creating a Task instance) */
+    if (fTakingSnapshotOnline)
     {
-        Bstr value;
-        HRESULT rc = GetExtraData(Bstr("VBoxInternal2/ForceTakeSnapshotWithoutState").raw(),
-                                  value.asOutParam());
-        if (FAILED(rc) || value != "1")
-            // creating a new online snapshot: we need a fresh saved state file
-            i_composeSavedStateFilename(aStateFilePath);
+        if (pTask->m_machineStateBackup != MachineState_Paused && !fPause)
+            i_setMachineState(MachineState_LiveSnapshotting);
+        else
+            i_setMachineState(MachineState_OnlineSnapshotting);
+        i_updateMachineStateOnClient();
     }
-    else if (mData->mMachineState == MachineState_Saved)
-        // taking an online snapshot from machine in "saved" state: then use existing state file
-        aStateFilePath = mSSData->strStateFilePath;
+    else
+        i_setMachineState(MachineState_Snapshotting);
+
+    pTask->m_pProgress.queryInterfaceTo(aProgress.asOutParam());
+
+    return rc;
+}
+
+/**
+ * Task thread implementation for SessionMachine::TakeSnapshot(), called from
+ * SessionMachine::taskHandler().
+ *
+ * @note Locks this object for writing.
+ *
+ * @param task
+ * @return
+ */
+void SessionMachine::i_takeSnapshotHandler(TakeSnapshotTask &task)
+{
+    LogFlowThisFuncEnter();
+
+    // Taking a snapshot consists of the following:
+    // 1) creating a Snapshot object with the current state of the machine
+    //    (hardware + storage)
+    // 2) creating a diff image for each virtual hard disk, into which write
+    //    operations go after the snapshot has been created
+    // 3) if the machine is online: saving the state of the virtual machine
+    //    (in the VM process)
+    // 4) reattach the hard disks
+    // 5) update the various snapshot/machine objects, save settings
 
-    if (aStateFilePath.isNotEmpty())
+    HRESULT rc = S_OK;
+    AutoCaller autoCaller(this);
+    LogFlowThisFunc(("state=%d\n", getObjectState().getState()));
+    if (FAILED(autoCaller.rc()))
     {
-        // ensure the directory for the saved state file exists
-        HRESULT rc = VirtualBox::i_ensureFilePathExists(aStateFilePath, true /* fCreate */);
-        if (FAILED(rc)) return rc;
+        /* we might have been uninitialized because the session was accidentally
+         * closed by the client, so don't assert */
+        rc = setError(E_FAIL,
+                      tr("The session has been accidentally closed"));
+        task.m_pProgress->i_notifyComplete(rc);
+        LogFlowThisFuncLeave();
+        return;
     }
 
-    /* create a snapshot machine object */
-    ComObjPtr<SnapshotMachine> snapshotMachine;
-    snapshotMachine.createObject();
-    HRESULT rc = snapshotMachine->init(this, snapshotId.ref(), aStateFilePath);
-    AssertComRCReturn(rc, rc);
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    /* create a snapshot object */
-    RTTIMESPEC time;
-    ComObjPtr<Snapshot> pSnapshot;
-    pSnapshot.createObject();
-    rc = pSnapshot->init(mParent,
-                         snapshotId,
-                         aName,
-                         aDescription,
-                         *RTTimeNow(&time),
-                         snapshotMachine,
-                         mData->mCurrentSnapshot);
-    AssertComRCReturnRC(rc);
-
-    /* fill in the snapshot data */
-    mConsoleTaskData.mLastState = mData->mMachineState;
-    mConsoleTaskData.mSnapshot = pSnapshot;
-
-    /// @todo in the long run the progress object should be moved to
-    // VBoxSVC to avoid trouble with monitoring the progress object state
-    // when the process where it lives is terminating shortly after the
-    // operation completed.
+    bool fBeganTakingSnapshot = false;
+    BOOL fSuspendedBySave     = FALSE;
 
     try
     {
+        // @todo: at this point we have to be in the right state!!!!
+        AssertStmt(   !Global::IsOnlineOrTransient(mData->mMachineState)
+                   || mData->mMachineState == MachineState_Snapshotting
+                   || mData->mMachineState == MachineState_OnlineSnapshotting
+                   || mData->mMachineState == MachineState_LiveSnapshotting, throw E_FAIL);
+        AssertStmt(task.m_machineStateBackup != mData->mMachineState, throw E_FAIL);
+        AssertStmt(task.m_pSnapshot.isNull(), throw E_FAIL);
+
+        if (   mData->mCurrentSnapshot
+            && mData->mCurrentSnapshot->i_getDepth() >= SETTINGS_SNAPSHOT_DEPTH_MAX)
+        {
+            throw setError(VBOX_E_INVALID_OBJECT_STATE,
+                           tr("Cannot take another snapshot for machine '%s', because it exceeds the maximum snapshot depth limit. Please delete some earlier snapshot which you no longer need"),
+                           mUserData->s.strName.c_str());
+        }
+
+        if (    !task.m_fTakingSnapshotOnline
+             && mData->mMachineState != MachineState_Saved)
+        {
+            /* save settings to ensure current changes are committed and
+             * hard disks are fixed up */
+            rc = i_saveSettings(NULL);
+                // no need to check for whether VirtualBox.xml needs changing since
+                // we can't have a machine XML rename pending at this point
+            if (FAILED(rc))
+                throw rc;
+        }
+
+        /* task.m_strStateFilePath is "" when the machine is offline or saved */
+        if (task.m_fTakingSnapshotOnline)
+        {
+            Bstr value;
+            rc = GetExtraData(Bstr("VBoxInternal2/ForceTakeSnapshotWithoutState").raw(),
+                              value.asOutParam());
+            if (FAILED(rc) || value != "1")
+                // creating a new online snapshot: we need a fresh saved state file
+                i_composeSavedStateFilename(task.m_strStateFilePath);
+        }
+        else if (mData->mMachineState == MachineState_Saved)
+            // taking an offline snapshot from machine in "saved" state: use existing state file
+            task.m_strStateFilePath = mSSData->strStateFilePath;
+
+        if (task.m_strStateFilePath.isNotEmpty())
+        {
+            // ensure the directory for the saved state file exists
+            rc = VirtualBox::i_ensureFilePathExists(task.m_strStateFilePath, true /* fCreate */);
+            if (FAILED(rc))
+                throw rc;
+        }
+
+        /* STEP 1: create the snapshot object */
+
+        /* create an ID for the snapshot */
+        Guid snapshotId;
+        snapshotId.create();
+
+        /* create a snapshot machine object */
+        ComObjPtr<SnapshotMachine> pSnapshotMachine;
+        pSnapshotMachine.createObject();
+        rc = pSnapshotMachine->init(this, snapshotId.ref(), task.m_strStateFilePath);
+        AssertComRCThrowRC(rc);
+
+        /* create a snapshot object */
+        RTTIMESPEC time;
+        RTTimeNow(&time);
+        task.m_pSnapshot.createObject();
+        rc = task.m_pSnapshot->init(mParent,
+                                    snapshotId,
+                                    task.m_strName,
+                                    task.m_strDescription,
+                                    time,
+                                    pSnapshotMachine,
+                                    mData->mCurrentSnapshot);
+        AssertComRCThrowRC(rc);
+
+        /* STEP 2: create the diff images */
         LogFlowThisFunc(("Creating differencing hard disks (online=%d)...\n",
-                         aFTakingSnapshotOnline));
+                         task.m_fTakingSnapshotOnline));
 
-        // backup the media data so we can recover if things goes wrong along the day;
-        // the matching commit() is in fixupMedia() during endSnapshot()
+        // Backup the media data so we can recover if something goes wrong.
+        // The matching commit() is in fixupMedia() during SessionMachine::i_finishTakingSnapshot()
         i_setModified(IsModified_Storage);
         mMediaData.backup();
 
-        /* Console::fntTakeSnapshotWorker and friends expects this. */
-        if (mConsoleTaskData.mLastState == MachineState_Running)
-            i_setMachineState(MachineState_LiveSnapshotting);
-        else
-            i_setMachineState(MachineState_Saving); /** @todo Confusing! Saving is used for both online and offline snapshots. */
-
         alock.release();
         /* create new differencing hard disks and attach them to this machine */
-        rc = i_createImplicitDiffs(aConsoleProgress,
-                                   1,            // operation weight; must be the same as in Console::TakeSnapshot()
-                                   !!aFTakingSnapshotOnline);
+        rc = i_createImplicitDiffs(task.m_pProgress,
+                                   1,            // operation weight; must be the same as in Machine::TakeSnapshot()
+                                   task.m_fTakingSnapshotOnline);
         if (FAILED(rc))
             throw rc;
+        alock.acquire();
 
         // MUST NOT save the settings or the media registry here, because
         // this causes trouble with rolling back settings if the user cancels
         // taking the snapshot after the diff images have been created.
+
+        fBeganTakingSnapshot = true;
+
+        /* Check sanity: for offline snapshots there must not be a saved state
+         * file name. All other combinations are valid (though online snapshots
+         * without saved state file seems inconsistent - there are exotic use
+         * cases, which need to be explicitly enabled, see the code above. */
+        if (   !task.m_fTakingSnapshotOnline
+            && !task.m_strStateFilePath.isEmpty())
+            throw setError(E_FAIL, "Invalid state of saved state file");
+
+        // STEP 3: save the VM state (if online)
+        if (task.m_fTakingSnapshotOnline)
+        {
+            task.m_pProgress->SetNextOperation(Bstr(tr("Saving the machine state")).raw(),
+                                               mHWData->mMemorySize);   // operation weight, same as computed
+                                                                        // when setting up progress object
+
+            if (task.m_strStateFilePath.isNotEmpty())
+            {
+                alock.release();
+                task.m_pProgress->i_setCancelCallback(i_takeSnapshotProgressCancelCallback, &task);
+                rc = task.m_pDirectControl->SaveStateWithReason(Reason_Snapshot,
+                                                                task.m_pProgress,
+                                                                Bstr(task.m_strStateFilePath).raw(),
+                                                                task.m_fPause,
+                                                                &fSuspendedBySave);
+                task.m_pProgress->i_setCancelCallback(NULL, NULL);
+                alock.acquire();
+                if (FAILED(rc))
+                    throw rc;
+            }
+            else
+                LogRel(("Machine: skipped saving state as part of online snapshot\n"));
+
+            if (!task.m_pProgress->i_notifyPointOfNoReturn())
+                throw setError(E_FAIL, tr("Canceled"));
+
+            // STEP 4: reattach hard disks
+            LogFlowThisFunc(("Reattaching new differencing hard disks...\n"));
+
+            task.m_pProgress->SetNextOperation(Bstr(tr("Reconfiguring medium attachments")).raw(),
+                                               1);       // operation weight, same as computed when setting up progress object
+
+            com::SafeIfaceArray<IMediumAttachment> atts;
+            rc = COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(atts));
+            if (FAILED(rc))
+                throw rc;
+
+            alock.release();
+            rc = task.m_pDirectControl->ReconfigureMediumAttachments(ComSafeArrayAsInParam(atts));
+            alock.acquire();
+            if (FAILED(rc))
+                throw rc;
+        }
+
+        /*
+         * Finalize the requested snapshot object. This will reset the
+         * machine state to the state it had at the beginning.
+         */
+        rc = i_finishTakingSnapshot(task, alock, true /*aSuccess*/);
+        // do not throw rc here because we can't call i_finishTakingSnapshot() twice
+        LogFlowThisFunc(("i_finishTakingSnapshot -> %Rhrc [mMachineState=%s]\n", rc, Global::stringifyMachineState(mData->mMachineState)));
     }
-    catch (HRESULT hrc)
+    catch (HRESULT rcThrown)
     {
-        LogThisFunc(("Caught %Rhrc [%s]\n", hrc, Global::stringifyMachineState(mData->mMachineState) ));
-        if (    mConsoleTaskData.mLastState != mData->mMachineState
-             && (   mConsoleTaskData.mLastState == MachineState_Running
-                  ? mData->mMachineState == MachineState_LiveSnapshotting
-                  : mData->mMachineState == MachineState_Saving)
-           )
-               i_setMachineState(mConsoleTaskData.mLastState);
+        rc = rcThrown;
+        LogThisFunc(("Caught %Rhrc [mMachineState=%s]\n", rc, Global::stringifyMachineState(mData->mMachineState)));
+
+        // @todo r=klaus check that the implicit diffs created above are cleaned up im the relevant error cases
 
-        pSnapshot->uninit();
-        pSnapshot.setNull();
-        mConsoleTaskData.mLastState = MachineState_Null;
-        mConsoleTaskData.mSnapshot.setNull();
+        /* preserve existing error info */
+        ErrorInfoKeeper eik;
 
-        rc = hrc;
+        if (fBeganTakingSnapshot)
+            i_finishTakingSnapshot(task, alock, false /*aSuccess*/);
 
-        // @todo r=dj what with the implicit diff that we created above? this is never cleaned up
+        // have to postpone this to the end as i_finishTakingSnapshot() needs
+        // it for various cleanup steps
+        task.m_pSnapshot->uninit();
+        task.m_pSnapshot.setNull();
     }
+    Assert(alock.isWriteLockOnCurrentThread());
+
+    {
+        // Keep all error information over the cleanup steps
+        ErrorInfoKeeper eik;
 
-    if (!(aFTakingSnapshotOnline && SUCCEEDED(rc)))
-        aStateFilePath = "";
+        /*
+         * Fix up the machine state.
+         *
+         * For offline snapshots we just update the local copy, for the other
+         * variants do the entire work. This ensures that the state is in sync
+         * with the VM process (in particular the VM execution state).
+         */
+        bool fNeedClientMachineStateUpdate = false;
+        if (   mData->mMachineState == MachineState_LiveSnapshotting
+            || mData->mMachineState == MachineState_OnlineSnapshotting
+            || mData->mMachineState == MachineState_Snapshotting)
+        {
+            if (!task.m_fTakingSnapshotOnline)
+                i_setMachineState(task.m_machineStateBackup);
+            else
+            {
+                MachineState_T enmMachineState = MachineState_Null;
+                HRESULT rc2 = task.m_pDirectControl->COMGETTER(NominalState)(&enmMachineState);
+                if (FAILED(rc2) || enmMachineState == MachineState_Null)
+                {
+                    AssertMsgFailed(("state=%s\n", Global::stringifyMachineState(enmMachineState)));
+                    // pure nonsense, try to continue somehow
+                    enmMachineState = MachineState_Aborted;
+                }
+                if (enmMachineState == MachineState_Paused)
+                {
+                    if (fSuspendedBySave)
+                    {
+                        alock.release();
+                        rc2 = task.m_pDirectControl->ResumeWithReason(Reason_Snapshot);
+                        alock.acquire();
+                        if (SUCCEEDED(rc2))
+                            enmMachineState = task.m_machineStateBackup;
+                    }
+                    else
+                        enmMachineState = task.m_machineStateBackup;
+                }
+                if (enmMachineState != mData->mMachineState)
+                {
+                    fNeedClientMachineStateUpdate = true;
+                    i_setMachineState(enmMachineState);
+                }
+            }
+        }
 
-    LogFlowThisFunc(("LEAVE - %Rhrc [%s]\n", rc, Global::stringifyMachineState(mData->mMachineState) ));
-    return rc;
+        /* check the remote state to see that we got it right. */
+        MachineState_T enmMachineState = MachineState_Null;
+        if (!task.m_pDirectControl.isNull())
+        {
+            ComPtr<IConsole> pConsole;
+            task.m_pDirectControl->COMGETTER(RemoteConsole)(pConsole.asOutParam());
+            if (!pConsole.isNull())
+                pConsole->COMGETTER(State)(&enmMachineState);
+        }
+        LogFlowThisFunc(("local mMachineState=%s remote mMachineState=%s\n",
+                         Global::stringifyMachineState(mData->mMachineState),
+                         Global::stringifyMachineState(enmMachineState)));
+
+        if (fNeedClientMachineStateUpdate)
+            i_updateMachineStateOnClient();
+    }
+
+    task.m_pProgress->i_notifyComplete(rc);
+
+    LogFlowThisFuncLeave();
+}
+
+
+/**
+ * Progress cancelation callback employed by SessionMachine::i_takeSnapshotHandler.
+ */
+/*static*/
+void SessionMachine::i_takeSnapshotProgressCancelCallback(void *pvUser)
+{
+    TakeSnapshotTask *pTask = (TakeSnapshotTask *)pvUser;
+    AssertPtrReturnVoid(pTask);
+    AssertReturnVoid(!pTask->m_pDirectControl.isNull());
+    pTask->m_pDirectControl->CancelSaveStateWithReason();
 }
 
+
 /**
- * Implementation for IInternalMachineControl::endTakingSnapshot().
- *
  * Called by the Console when it's done saving the VM state into the snapshot
  * (if online) and reconfiguring the hard disks. See BeginTakingSnapshot() above.
  *
@@ -1592,42 +1830,28 @@ HRESULT SessionMachine::beginTakingSnapshot(const ComPtr<IConsole> &aInitiator,
  * @param aSuccess Whether Console was successful with the client-side snapshot things.
  * @return
  */
-HRESULT SessionMachine::endTakingSnapshot(BOOL aSuccess)
+HRESULT SessionMachine::i_finishTakingSnapshot(TakeSnapshotTask &task, AutoWriteLock &alock, bool aSuccess)
 {
     LogFlowThisFunc(("\n"));
 
-    AutoWriteLock machineLock(this COMMA_LOCKVAL_SRC_POS);
+    Assert(alock.isWriteLockOnCurrentThread());
 
     AssertReturn(   !aSuccess
-                 || (    (    mData->mMachineState == MachineState_Saving
-                           || mData->mMachineState == MachineState_LiveSnapshotting)
-                      && mConsoleTaskData.mLastState != MachineState_Null
-                      && !mConsoleTaskData.mSnapshot.isNull()
-                    )
-                 , E_FAIL);
-
-    /*
-     * Restore the state we had when BeginTakingSnapshot() was called,
-     * Console::fntTakeSnapshotWorker restores its local copy when we return.
-     * If the state was Running, then let Console::fntTakeSnapshotWorker do it
-     * all to avoid races.
-     */
-    if (    mData->mMachineState != mConsoleTaskData.mLastState
-         && mConsoleTaskData.mLastState != MachineState_Running
-       )
-           i_setMachineState(mConsoleTaskData.mLastState);
+                 || mData->mMachineState == MachineState_Snapshotting
+                 || mData->mMachineState == MachineState_OnlineSnapshotting
+                 || mData->mMachineState == MachineState_LiveSnapshotting, E_FAIL);
 
     ComObjPtr<Snapshot> pOldFirstSnap = mData->mFirstSnapshot;
     ComObjPtr<Snapshot> pOldCurrentSnap = mData->mCurrentSnapshot;
 
-    bool fOnline = Global::IsOnline(mConsoleTaskData.mLastState);
+    bool fOnline = Global::IsOnline(task.m_machineStateBackup);
 
     HRESULT rc = S_OK;
 
     if (aSuccess)
     {
         // new snapshot becomes the current one
-        mData->mCurrentSnapshot = mConsoleTaskData.mSnapshot;
+        mData->mCurrentSnapshot = task.m_pSnapshot;
 
         /* memorize the first snapshot if necessary */
         if (!mData->mFirstSnapshot)
@@ -1650,14 +1874,14 @@ HRESULT SessionMachine::endTakingSnapshot(BOOL aSuccess)
 
         /* inform callbacks */
         mParent->i_onSnapshotTaken(mData->mUuid,
-                                   mConsoleTaskData.mSnapshot->i_getId());
-        machineLock.release();
+                                   task.m_pSnapshot->i_getId());
+        alock.release();
     }
     else
     {
         /* delete all differencing hard disks created (this will also attach
          * their parents back by rolling back mMediaData) */
-        machineLock.release();
+        alock.release();
 
         i_rollbackMedia();
 
@@ -1669,56 +1893,53 @@ HRESULT SessionMachine::endTakingSnapshot(BOOL aSuccess)
             // no need to test for whether the saved state file is shared: an online
             // snapshot means that a new saved state file was created, which we must
             // clean up now
-            RTFileDelete(mConsoleTaskData.mSnapshot->i_getStateFilePath().c_str());
-            machineLock.acquire();
+            RTFileDelete(task.m_pSnapshot->i_getStateFilePath().c_str());
 
+        alock.acquire();
 
-        mConsoleTaskData.mSnapshot->uninit();
-        machineLock.release();
+        task.m_pSnapshot->uninit();
+        alock.release();
 
     }
 
     /* clear out the snapshot data */
-    mConsoleTaskData.mLastState = MachineState_Null;
-    mConsoleTaskData.mSnapshot.setNull();
-
-    /* machineLock has been released already */
+    task.m_pSnapshot.setNull();
 
+    /* alock has been released already */
     mParent->i_saveModifiedRegistries();
 
+    alock.acquire();
+
     return rc;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-// RestoreSnapshot methods (SessionMachine and related tasks)
+// RestoreSnapshot methods (Machine and related tasks)
 //
 ////////////////////////////////////////////////////////////////////////////////
 
+HRESULT Machine::restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot,
+                                 ComPtr<IProgress> &aProgress)
+{
+    NOREF(aSnapshot);
+    NOREF(aProgress);
+    ReturnComNotImplemented();
+}
+
 /**
- * Implementation for IInternalMachineControl::restoreSnapshot().
- *
- * Gets called from Console::RestoreSnapshot(), and that's basically the
- * only thing Console does. Restoring a snapshot happens entirely on the
- * server side since the machine cannot be running.
- *
- * This creates a new thread that does the work and returns a progress
- * object to the client which is then returned to the caller of
- * Console::RestoreSnapshot().
+ * Restoring a snapshot happens entirely on the server side, the machine cannot be running.
  *
+ * This creates a new thread that does the work and returns a progress object to the client.
  * Actual work then takes place in RestoreSnapshotTask::handler().
  *
  * @note Locks this + children objects for writing!
  *
- * @param aInitiator in: rhe console on which Console::RestoreSnapshot was called.
  * @param aSnapshot in: the snapshot to restore.
- * @param aMachineState in: client-side machine state.
  * @param aProgress out: progress object to monitor restore thread.
  * @return
  */
-HRESULT SessionMachine::restoreSnapshot(const ComPtr<IConsole> &aInitiator,
-                                        const ComPtr<ISnapshot> &aSnapshot,
-                                        MachineState_T *aMachineState,
+HRESULT SessionMachine::restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot,
                                         ComPtr<IProgress> &aProgress)
 {
     LogFlowThisFuncEnter();
@@ -1726,8 +1947,14 @@ HRESULT SessionMachine::restoreSnapshot(const ComPtr<IConsole> &aInitiator,
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     // machine must not be running
-    ComAssertRet(!Global::IsOnlineOrTransient(mData->mMachineState),
-                 E_FAIL);
+    if (Global::IsOnlineOrTransient(mData->mMachineState))
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Cannot delete the current state of the running machine (machine state: %s)"),
+                        Global::stringifyMachineState(mData->mMachineState));
+
+    HRESULT rc = i_checkStateDependency(MutableOrSavedStateDep);
+    if (FAILED(rc))
+        return rc;
 
     ISnapshot* iSnapshot = aSnapshot;
     ComObjPtr<Snapshot> pSnapshot(static_cast<Snapshot*>(iSnapshot));
@@ -1757,7 +1984,7 @@ HRESULT SessionMachine::restoreSnapshot(const ComPtr<IConsole> &aInitiator,
 
     ComObjPtr<Progress> pProgress;
     pProgress.createObject();
-    pProgress->init(mParent, aInitiator,
+    pProgress->init(mParent, static_cast<IMachine*>(this),
                     BstrFmt(tr("Restoring snapshot '%s'"), pSnapshot->i_getName().c_str()).raw(),
                     FALSE /* aCancelable */,
                     ulOpCount,
@@ -1767,21 +1994,13 @@ HRESULT SessionMachine::restoreSnapshot(const ComPtr<IConsole> &aInitiator,
 
     /* create and start the task on a separate thread (note that it will not
      * start working until we release alock) */
-    RestoreSnapshotTask *task = new RestoreSnapshotTask(this,
-                                                        pProgress,
-                                                        pSnapshot);
-    int vrc = RTThreadCreate(NULL,
-                             taskHandler,
-                             (void*)task,
-                             0,
-                             RTTHREADTYPE_MAIN_WORKER,
-                             0,
-                             "RestoreSnap");
-    if (RT_FAILURE(vrc))
-    {
-        delete task;
-        ComAssertRCRet(vrc, E_FAIL);
-    }
+    RestoreSnapshotTask *pTask = new RestoreSnapshotTask(this,
+                                                         pProgress,
+                                                         "RestoreSnap",
+                                                         pSnapshot);
+    rc = pTask->createThread();
+    if (FAILED(rc))
+        return rc;
 
     /* set the proper machine state (note: after creating a Task instance) */
     i_setMachineState(MachineState_RestoringSnapshot);
@@ -1789,9 +2008,6 @@ HRESULT SessionMachine::restoreSnapshot(const ComPtr<IConsole> &aInitiator,
     /* return the progress to the caller */
     pProgress.queryInterfaceTo(aProgress.asOutParam());
 
-    /* return the new state to the caller */
-    *aMachineState = mData->mMachineState;
-
     LogFlowThisFuncLeave();
 
     return S_OK;
@@ -1807,9 +2023,9 @@ HRESULT SessionMachine::restoreSnapshot(const ComPtr<IConsole> &aInitiator,
  *
  * @note Locks mParent + this object for writing.
  *
- * @param aTask Task data.
+ * @param pTask Task data.
  */
-void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
+void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &task)
 {
     LogFlowThisFuncEnter();
 
@@ -1820,10 +2036,10 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
     {
         /* we might have been uninitialized because the session was accidentally
          * closed by the client, so don't assert */
-        aTask.pProgress->i_notifyComplete(E_FAIL,
-                                          COM_IIDOF(IMachine),
-                                          getComponentName(),
-                                          tr("The session has been accidentally closed"));
+        task.m_pProgress->i_notifyComplete(E_FAIL,
+                                           COM_IIDOF(IMachine),
+                                           getComponentName(),
+                                           tr("The session has been accidentally closed"));
 
         LogFlowThisFuncLeave();
         return;
@@ -1845,7 +2061,7 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
 
         /* Delete the saved state file if the machine was Saved prior to this
          * operation */
-        if (aTask.machineStateBackup == MachineState_Saved)
+        if (task.m_machineStateBackup == MachineState_Saved)
         {
             Assert(!mSSData->strStateFilePath.isEmpty());
 
@@ -1855,7 +2071,7 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
             mSSData->strStateFilePath.setNull();
             i_releaseSavedStateFile(strStateFile, NULL /* pSnapshotToIgnore */ );
 
-            aTask.modifyBackedUpState(MachineState_PoweredOff);
+            task.modifyBackedUpState(MachineState_PoweredOff);
 
             rc = i_saveStateSettings(SaveSTS_StateFilePath);
             if (FAILED(rc))
@@ -1866,12 +2082,12 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
         RTTimeSpecSetMilli(&snapshotTimeStamp, 0);
 
         {
-            AutoReadLock snapshotLock(aTask.pSnapshot COMMA_LOCKVAL_SRC_POS);
+            AutoReadLock snapshotLock(task.m_pSnapshot COMMA_LOCKVAL_SRC_POS);
 
             /* remember the timestamp of the snapshot we're restoring from */
-            snapshotTimeStamp = aTask.pSnapshot->i_getTimeStamp();
+            snapshotTimeStamp = task.m_pSnapshot->i_getTimeStamp();
 
-            ComPtr<SnapshotMachine> pSnapshotMachine(aTask.pSnapshot->i_getSnapshotMachine());
+            ComPtr<SnapshotMachine> pSnapshotMachine(task.m_pSnapshot->i_getSnapshotMachine());
 
             /* copy all hardware data from the snapshot */
             i_copyFrom(pSnapshotMachine);
@@ -1896,7 +2112,7 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
             snapshotLock.release();
             alock.release();
 
-            rc = i_createImplicitDiffs(aTask.pProgress,
+            rc = i_createImplicitDiffs(task.m_pProgress,
                                        1,
                                        false /* aOnline */);
             if (FAILED(rc))
@@ -1906,22 +2122,22 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
             snapshotLock.acquire();
 
             /* Note: on success, current (old) hard disks will be
-             * deassociated/deleted on #commit() called from #saveSettings() at
+             * deassociated/deleted on #commit() called from #i_saveSettings() at
              * the end. On failure, newly created implicit diffs will be
              * deleted by #rollback() at the end. */
 
             /* should not have a saved state file associated at this point */
             Assert(mSSData->strStateFilePath.isEmpty());
 
-            const Utf8Str &strSnapshotStateFile = aTask.pSnapshot->i_getStateFilePath();
+            const Utf8Str &strSnapshotStateFile = task.m_pSnapshot->i_getStateFilePath();
 
             if (strSnapshotStateFile.isNotEmpty())
                 // online snapshot: then share the state file
                 mSSData->strStateFilePath = strSnapshotStateFile;
 
-            LogFlowThisFunc(("Setting new current snapshot {%RTuuid}\n", aTask.pSnapshot->i_getId().raw()));
+            LogFlowThisFunc(("Setting new current snapshot {%RTuuid}\n", task.m_pSnapshot->i_getId().raw()));
             /* make the snapshot we restored from the current snapshot */
-            mData->mCurrentSnapshot = aTask.pSnapshot;
+            mData->mCurrentSnapshot = task.m_pSnapshot;
         }
 
         /* grab differencing hard disks from the old attachments that will
@@ -1956,7 +2172,6 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
         else
             i_setMachineState(MachineState_PoweredOff);
 
-        i_updateMachineStateOnClient();
         stateRestored = true;
 
         /* Paranoia: no one must have saved the settings in the mean time. If
@@ -1968,7 +2183,7 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
         mData->mLastStateChange = snapshotTimeStamp;
 
         // detach the current-state diffs that we detected above and build a list of
-        // image files to delete _after_ saveSettings()
+        // image files to delete _after_ i_saveSettings()
 
         MediaList llDiffsToDelete;
 
@@ -1984,13 +2199,13 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
             LogFlowThisFunc(("Detaching old current state in differencing image '%s'\n", pMedium->i_getName().c_str()));
 
             // Normally we "detach" the medium by removing the attachment object
-            // from the current machine data; saveSettings() below would then
+            // from the current machine data; i_saveSettings() below would then
             // compare the current machine data with the one in the backup
             // and actually call Medium::removeBackReference(). But that works only half
             // the time in our case so instead we force a detachment here:
             // remove from machine data
             mMediaData->mAttachments.remove(pAttach);
-            // Remove it from the backup or else saveSettings will try to detach
+            // Remove it from the backup or else i_saveSettings will try to detach
             // it again and assert. The paranoia check avoids crashes (see
             // assert above) if this code is buggy and saves settings in the
             // wrong place.
@@ -2008,12 +2223,11 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
                             SaveS_ResetCurStateModified);
         if (FAILED(rc))
             throw rc;
-        // unconditionally add the parent registry. We do similar in SessionMachine::EndTakingSnapshot
-        // (mParent->saveSettings())
 
         // release the locks before updating registry and deleting image files
         alock.release();
 
+        // unconditionally add the parent registry.
         mParent->i_markRegistryModified(mParent->i_getGlobalRegistryId());
 
         // from here on we cannot roll back on failure any more
@@ -2027,7 +2241,7 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
 
             HRESULT rc2 = pMedium->i_deleteStorage(NULL /* aProgress */,
                                                    true /* aWait */);
-            // ignore errors here because we cannot roll back after saveSettings() above
+            // ignore errors here because we cannot roll back after i_saveSettings() above
             if (SUCCEEDED(rc2))
                 pMedium->uninit();
         }
@@ -2048,18 +2262,17 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
         if (!stateRestored)
         {
             /* restore the machine state */
-            i_setMachineState(aTask.machineStateBackup);
-            i_updateMachineStateOnClient();
+            i_setMachineState(task.m_machineStateBackup);
         }
     }
 
     mParent->i_saveModifiedRegistries();
 
     /* set the result (this will try to fetch current error info on failure) */
-    aTask.pProgress->i_notifyComplete(rc);
+    task.m_pProgress->i_notifyComplete(rc);
 
     if (SUCCEEDED(rc))
-        mParent->i_onSnapshotDeleted(mData->mUuid, Guid());
+        mParent->i_onSnapshotRestored(mData->mUuid, Guid());
 
     LogFlowThisFunc(("Done restoring snapshot (rc=%08X)\n", rc));
 
@@ -2072,33 +2285,72 @@ void SessionMachine::i_restoreSnapshotHandler(RestoreSnapshotTask &aTask)
 //
 ////////////////////////////////////////////////////////////////////////////////
 
+HRESULT Machine::deleteSnapshot(const com::Guid &aId, ComPtr<IProgress> &aProgress)
+{
+    NOREF(aId);
+    NOREF(aProgress);
+    ReturnComNotImplemented();
+}
+
+HRESULT SessionMachine::deleteSnapshot(const com::Guid &aId, ComPtr<IProgress> &aProgress)
+{
+    return i_deleteSnapshot(aId, aId,
+                            FALSE /* fDeleteAllChildren */,
+                            aProgress);
+}
+
+HRESULT Machine::deleteSnapshotAndAllChildren(const com::Guid &aId, ComPtr<IProgress> &aProgress)
+{
+    NOREF(aId);
+    NOREF(aProgress);
+    ReturnComNotImplemented();
+}
+
+HRESULT SessionMachine::deleteSnapshotAndAllChildren(const com::Guid &aId, ComPtr<IProgress> &aProgress)
+{
+    return i_deleteSnapshot(aId, aId,
+                            TRUE /* fDeleteAllChildren */,
+                            aProgress);
+}
+
+HRESULT Machine::deleteSnapshotRange(const com::Guid &aStartId, const com::Guid &aEndId, ComPtr<IProgress> &aProgress)
+{
+    NOREF(aStartId);
+    NOREF(aEndId);
+    NOREF(aProgress);
+    ReturnComNotImplemented();
+}
+
+HRESULT SessionMachine::deleteSnapshotRange(const com::Guid &aStartId, const com::Guid &aEndId, ComPtr<IProgress> &aProgress)
+{
+    return i_deleteSnapshot(aStartId, aEndId,
+                            FALSE /* fDeleteAllChildren */,
+                            aProgress);
+}
+
+
 /**
- * Implementation for IInternalMachineControl::deleteSnapshot().
+ * Implementation for SessionMachine::i_deleteSnapshot().
  *
- * Gets called from Console::DeleteSnapshot(), and that's basically the
- * only thing Console does initially. Deleting a snapshot happens entirely on
- * the server side if the machine is not running, and if it is running then
- * the individual merges are done via internal session callbacks.
+ * Gets called from SessionMachine::DeleteSnapshot(). Deleting a snapshot
+ * happens entirely on the server side if the machine is not running, and
+ * if it is running then the merges are done via internal session callbacks.
  *
  * This creates a new thread that does the work and returns a progress
- * object to the client which is then returned to the caller of
- * Console::DeleteSnapshot().
+ * object to the client.
  *
- * Actual work then takes place in DeleteSnapshotTask::handler().
+ * Actual work then takes place in SessionMachine::i_deleteSnapshotHandler().
  *
  * @note Locks mParent + this + children objects for writing!
  */
-HRESULT SessionMachine::deleteSnapshot(const ComPtr<IConsole> &aInitiator,
-                                       const com::Guid &aStartId,
-                                       const com::Guid &aEndId,
-                                       BOOL aDeleteAllChildren,
-                                       MachineState_T *aMachineState,
-                                       ComPtr<IProgress> &aProgress)
+HRESULT SessionMachine::i_deleteSnapshot(const com::Guid &aStartId,
+                                         const com::Guid &aEndId,
+                                         BOOL aDeleteAllChildren,
+                                         ComPtr<IProgress> &aProgress)
 {
     LogFlowThisFuncEnter();
 
-    AssertReturn(aInitiator && !aStartId.isZero() && !aEndId.isZero() && aStartId.isValid() && aEndId.isValid(), E_INVALIDARG);
-
+    AssertReturn(!aStartId.isZero() && !aEndId.isZero() && aStartId.isValid() && aEndId.isValid(), E_INVALIDARG);
 
     /** @todo implement the "and all children" and "range" variants */
     if (aDeleteAllChildren || aStartId != aEndId)
@@ -2106,6 +2358,11 @@ HRESULT SessionMachine::deleteSnapshot(const ComPtr<IConsole> &aInitiator,
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
+    if (Global::IsTransient(mData->mMachineState))
+        return setError(VBOX_E_INVALID_VM_STATE,
+                        tr("Cannot delete a snapshot of the machine while it is changing the state (machine state: %s)"),
+                        Global::stringifyMachineState(mData->mMachineState));
+
     // be very picky about machine states
     if (   Global::IsOnlineOrTransient(mData->mMachineState)
         && mData->mMachineState != MachineState_PoweredOff
@@ -2118,9 +2375,14 @@ HRESULT SessionMachine::deleteSnapshot(const ComPtr<IConsole> &aInitiator,
                         tr("Invalid machine state: %s"),
                         Global::stringifyMachineState(mData->mMachineState));
 
+    HRESULT rc = i_checkStateDependency(MutableOrSavedOrRunningStateDep);
+    if (FAILED(rc))
+        return rc;
+
     ComObjPtr<Snapshot> pSnapshot;
-    HRESULT rc = i_findSnapshotById(aStartId, pSnapshot, true /* aSetError */);
-    if (FAILED(rc)) return rc;
+    rc = i_findSnapshotById(aStartId, pSnapshot, true /* aSetError */);
+    if (FAILED(rc))
+        return rc;
 
     AutoWriteLock snapshotLock(pSnapshot COMMA_LOCKVAL_SRC_POS);
     Utf8Str str;
@@ -2199,7 +2461,7 @@ HRESULT SessionMachine::deleteSnapshot(const ComPtr<IConsole> &aInitiator,
 
     ComObjPtr<Progress> pProgress;
     pProgress.createObject();
-    pProgress->init(mParent, aInitiator,
+    pProgress->init(mParent, static_cast<IMachine*>(this),
                     BstrFmt(tr("Deleting snapshot '%s'"), pSnapshot->i_getName().c_str()).raw(),
                     FALSE /* aCancelable */,
                     ulOpCount,
@@ -2211,37 +2473,33 @@ HRESULT SessionMachine::deleteSnapshot(const ComPtr<IConsole> &aInitiator,
                           || (mData->mMachineState == MachineState_Paused));
 
     /* create and start the task on a separate thread */
-    DeleteSnapshotTask *task = new DeleteSnapshotTask(this, pProgress,
-                                                      fDeleteOnline, pSnapshot);
-    int vrc = RTThreadCreate(NULL,
-                             taskHandler,
-                             (void*)task,
-                             0,
-                             RTTHREADTYPE_MAIN_WORKER,
-                             0,
-                             "DeleteSnapshot");
-    if (RT_FAILURE(vrc))
-    {
-        delete task;
-        return E_FAIL;
-    }
+    DeleteSnapshotTask *pTask = new DeleteSnapshotTask(this, pProgress,
+                                                       "DeleteSnap",
+                                                       fDeleteOnline,
+                                                       pSnapshot);
+    rc = pTask->createThread();
+    if (FAILED(rc))
+        return rc;
 
     // the task might start running but will block on acquiring the machine's write lock
     // which we acquired above; once this function leaves, the task will be unblocked;
     // set the proper machine state here now (note: after creating a Task instance)
     if (mData->mMachineState == MachineState_Running)
+    {
         i_setMachineState(MachineState_DeletingSnapshotOnline);
+        i_updateMachineStateOnClient();
+    }
     else if (mData->mMachineState == MachineState_Paused)
+    {
         i_setMachineState(MachineState_DeletingSnapshotPaused);
+        i_updateMachineStateOnClient();
+    }
     else
         i_setMachineState(MachineState_DeletingSnapshot);
 
     /* return the progress to the caller */
     pProgress.queryInterfaceTo(aProgress.asOutParam());
 
-    /* return the new state to the caller */
-    *aMachineState = mData->mMachineState;
-
     LogFlowThisFuncLeave();
 
     return S_OK;
@@ -2340,29 +2598,26 @@ typedef std::list<MediumDeleteRec> MediumDeleteRecList;
  *
  * @note Locks the machine + the snapshot + the media tree for writing!
  *
- * @param aTask Task data.
+ * @param pTask Task data.
  */
-
-void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
+void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &task)
 {
     LogFlowThisFuncEnter();
 
+    HRESULT rc = S_OK;
     AutoCaller autoCaller(this);
-
     LogFlowThisFunc(("state=%d\n", getObjectState().getState()));
-    if (!autoCaller.isOk())
+    if (FAILED(autoCaller.rc()))
     {
         /* we might have been uninitialized because the session was accidentally
          * closed by the client, so don't assert */
-        aTask.pProgress->i_notifyComplete(E_FAIL,
-                                          COM_IIDOF(IMachine),
-                                          getComponentName(),
-                                          tr("The session has been accidentally closed"));
+        rc = setError(E_FAIL,
+                      tr("The session has been accidentally closed"));
+        task.m_pProgress->i_notifyComplete(rc);
         LogFlowThisFuncLeave();
         return;
     }
 
-    HRESULT rc = S_OK;
     MediumDeleteRecList toDelete;
     Guid snapshotId;
 
@@ -2370,7 +2625,7 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
     {
         /* Locking order:  */
         AutoMultiWriteLock2 multiLock(this->lockHandle(),                   // machine
-                                      aTask.pSnapshot->lockHandle()         // snapshot
+                                      task.m_pSnapshot->lockHandle()        // snapshot
                                       COMMA_LOCKVAL_SRC_POS);
         // once we have this lock, we know that SessionMachine::DeleteSnapshot()
         // has exited after setting the machine state to MachineState_DeletingSnapshot
@@ -2378,12 +2633,12 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
         AutoWriteLock treeLock(mParent->i_getMediaTreeLockHandle()
                                COMMA_LOCKVAL_SRC_POS);
 
-        ComObjPtr<SnapshotMachine> pSnapMachine = aTask.pSnapshot->i_getSnapshotMachine();
+        ComObjPtr<SnapshotMachine> pSnapMachine = task.m_pSnapshot->i_getSnapshotMachine();
         // no need to lock the snapshot machine since it is const by definition
         Guid machineId = pSnapMachine->i_getId();
 
         // save the snapshot ID (for callbacks)
-        snapshotId = aTask.pSnapshot->i_getId();
+        snapshotId = task.m_pSnapshot->i_getId();
 
         // first pass:
         LogFlowThisFunc(("1: Checking hard disk merge prerequisites...\n"));
@@ -2427,7 +2682,7 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
             ComObjPtr<Medium> pParentForTarget;
             MediumLockList *pChildrenToReparent = NULL;
             bool fNeedsOnlineMerge = false;
-            bool fOnlineMergePossible = aTask.m_fDeleteOnline;
+            bool fOnlineMergePossible = task.m_fDeleteOnline;
             MediumLockList *pMediumLockList = NULL;
             MediumLockList *pVMMALockList = NULL;
             ComPtr<IToken> pHDLockToken;
@@ -2665,13 +2920,13 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
             // tree is protected by the machine lock as well
             AutoWriteLock machineLock(this COMMA_LOCKVAL_SRC_POS);
 
-            Utf8Str stateFilePath = aTask.pSnapshot->i_getStateFilePath();
+            Utf8Str stateFilePath = task.m_pSnapshot->i_getStateFilePath();
             if (!stateFilePath.isEmpty())
             {
-                aTask.pProgress->SetNextOperation(Bstr(tr("Deleting the execution state")).raw(),
-                                                  1);        // weight
+                task.m_pProgress->SetNextOperation(Bstr(tr("Deleting the execution state")).raw(),
+                                                   1);        // weight
 
-                i_releaseSavedStateFile(stateFilePath, aTask.pSnapshot /* pSnapshotToIgnore */);
+                i_releaseSavedStateFile(stateFilePath, task.m_pSnapshot /* pSnapshotToIgnore */);
 
                 // machine will need saving now
                 machineLock.release();
@@ -2696,9 +2951,9 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
                 ulWeight = (ULONG)(pMedium->i_getSize() / _1M);
             }
 
-            aTask.pProgress->SetNextOperation(BstrFmt(tr("Merging differencing image '%s'"),
-                                              pMedium->i_getName().c_str()).raw(),
-                                              ulWeight);
+            task.m_pProgress->SetNextOperation(BstrFmt(tr("Merging differencing image '%s'"),
+                                               pMedium->i_getName().c_str()).raw(),
+                                               ulWeight);
 
             bool fNeedSourceUninit = false;
             bool fReparentTarget = false;
@@ -2721,7 +2976,7 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
                     Assert(pMedium->i_getState() == MediumState_Deleting);
                     /* No need to hold the lock any longer. */
                     mLock.release();
-                    rc = pMedium->i_deleteStorage(&aTask.pProgress,
+                    rc = pMedium->i_deleteStorage(&task.m_pProgress,
                                                   true /* aWait */);
                     if (FAILED(rc))
                         throw rc;
@@ -2739,6 +2994,7 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
                     // SessionMachine::FinishOnlineMergeMedium can get at it.
                     // This callback will arrive while onlineMergeMedium is
                     // still executing, and there can't be two tasks.
+                    /// @todo r=klaus this hack needs to go, and the logic needs to be "unconvoluted", putting SessionMachine in charge of coordinating the reconfig/resume.
                     mConsoleTaskData.mDeleteSnapshotInfo = (void *)&(*it);
                     // online medium merge, in the direction decided earlier
                     rc = i_onlineMergeMedium(it->mpOnlineMediumAttachment,
@@ -2748,7 +3004,7 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
                                              it->mpParentForTarget,
                                              it->mpChildrenToReparent,
                                              it->mpMediumLockList,
-                                             aTask.pProgress,
+                                             task.m_pProgress,
                                              &fNeedsSave);
                     mConsoleTaskData.mDeleteSnapshotInfo = NULL;
                 }
@@ -2760,7 +3016,7 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
                                                  it->mpParentForTarget,
                                                  it->mpChildrenToReparent,
                                                  it->mpMediumLockList,
-                                                 &aTask.pProgress,
+                                                 &task.m_pProgress,
                                                  true /* aWait */);
                 }
 
@@ -2825,7 +3081,7 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
                 // There can be only one child snapshot in this case.
                 ComObjPtr<Machine> pMachine = this;
                 Guid childSnapshotId;
-                ComObjPtr<Snapshot> pChildSnapshot = aTask.pSnapshot->i_getFirstChild();
+                ComObjPtr<Snapshot> pChildSnapshot = task.m_pSnapshot->i_getFirstChild();
                 if (pChildSnapshot)
                 {
                     pMachine = pChildSnapshot->i_getSnapshotMachine();
@@ -2870,8 +3126,8 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
             // tree is protected by the machine lock as well
             AutoWriteLock machineLock(this COMMA_LOCKVAL_SRC_POS);
 
-            aTask.pSnapshot->i_beginSnapshotDelete();
-            aTask.pSnapshot->uninit();
+            task.m_pSnapshot->i_beginSnapshotDelete();
+            task.m_pSnapshot->uninit();
 
             machineLock.release();
             mParent->i_markRegistryModified(i_getId());
@@ -2911,14 +3167,15 @@ void SessionMachine::i_deleteSnapshotHandler(DeleteSnapshotTask &aTask)
 
         // restore the machine state that was saved when the
         // task was started
-        i_setMachineState(aTask.machineStateBackup);
-        i_updateMachineStateOnClient();
+        i_setMachineState(task.m_machineStateBackup);
+        if (Global::IsOnline(mData->mMachineState))
+            i_updateMachineStateOnClient();
 
         mParent->i_saveModifiedRegistries();
     }
 
     // report the result (this will try to fetch current error info on failure)
-    aTask.pProgress->i_notifyComplete(rc);
+    task.m_pProgress->i_notifyComplete(rc);
 
     if (SUCCEEDED(rc))
         mParent->i_onSnapshotDeleted(mData->mUuid, snapshotId);
@@ -3060,13 +3317,13 @@ HRESULT SessionMachine::i_prepareDeleteSnapshotMedium(const ComObjPtr<Medium> &a
         {
             aSource = aHD;
             aTarget = pChild;
-            LogFlowFunc(("Forward merging selected\n"));
+            LogFlowThisFunc(("Forward merging selected\n"));
         }
         else
         {
             aSource = pChild;
             aTarget = aHD;
-            LogFlowFunc(("Backward merging selected\n"));
+            LogFlowThisFunc(("Backward merging selected\n"));
         }
     }
 
@@ -3579,7 +3836,9 @@ HRESULT SessionMachine::finishOnlineMergeMedium()
             rc = pMediumLockList->RemoveByIterator(it);
             AssertComRC(rc);
 
+            treeLock.release();
             pMedium->uninit();
+            treeLock.acquire();
         }
 
         /* Stop as soon as we reached the last medium affected by the merge.
diff --git a/src/VBox/Main/src-server/VirtualBoxImpl.cpp b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
index ef7c337..2001e58 100644
--- a/src/VBox/Main/src-server/VirtualBoxImpl.cpp
+++ b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
@@ -1871,7 +1871,10 @@ HRESULT VirtualBox::openMedium(const com::Utf8Str &aLocation,
             }
         }
         else
-            rc = VBOX_E_OBJECT_NOT_FOUND;
+        {
+            if (rc != VBOX_E_INVALID_OBJECT_STATE)
+                rc = VBOX_E_OBJECT_NOT_FOUND;
+        }
     }
 
     if (SUCCEEDED(rc))
@@ -2810,7 +2813,7 @@ void VirtualBox::i_onSessionStateChange(const Guid &aId, SessionState_T aState)
     i_postEvent(new SessionEvent(this, aId, aState));
 }
 
-/** Event for onSnapshotTaken(), onSnapshotDeleted() and onSnapshotChange() */
+/** Event for i_onSnapshotTaken(), i_onSnapshotDeleted(), i_onSnapshotRestored() and i_onSnapshotChange() */
 struct SnapshotEvent : public VirtualBox::CallbackEvent
 {
     SnapshotEvent(VirtualBox *aVB, const Guid &aMachineId, const Guid &aSnapshotId,
@@ -2835,7 +2838,7 @@ struct SnapshotEvent : public VirtualBox::CallbackEvent
 void VirtualBox::i_onSnapshotTaken(const Guid &aMachineId, const Guid &aSnapshotId)
 {
     i_postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId,
-                                VBoxEventType_OnSnapshotTaken));
+                                  VBoxEventType_OnSnapshotTaken));
 }
 
 /**
@@ -2844,7 +2847,16 @@ void VirtualBox::i_onSnapshotTaken(const Guid &aMachineId, const Guid &aSnapshot
 void VirtualBox::i_onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapshotId)
 {
     i_postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId,
-                                VBoxEventType_OnSnapshotDeleted));
+                                  VBoxEventType_OnSnapshotDeleted));
+}
+
+/**
+ *  @note Doesn't lock any object.
+ */
+void VirtualBox::i_onSnapshotRestored(const Guid &aMachineId, const Guid &aSnapshotId)
+{
+    i_postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId,
+                                  VBoxEventType_OnSnapshotRestored));
 }
 
 /**
@@ -2853,7 +2865,7 @@ void VirtualBox::i_onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapsh
 void VirtualBox::i_onSnapshotChange(const Guid &aMachineId, const Guid &aSnapshotId)
 {
     i_postEvent(new SnapshotEvent(this, aMachineId, aSnapshotId,
-                                VBoxEventType_OnSnapshotChanged));
+                                  VBoxEventType_OnSnapshotChanged));
 }
 
 /** Event for onGuestPropertyChange() */
diff --git a/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp b/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
index 026ca96..ddb2778 100644
--- a/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
+++ b/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
@@ -76,12 +76,12 @@ void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *, void *, void *inf
 {
     HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)info;
 
-    ALock l(pThis);
+    RTCLock grab(pThis->m_LockMtx);
     pThis->updateInfo();
 }
 
 
-HRESULT HostDnsServiceDarwin::init()
+HRESULT HostDnsServiceDarwin::init(VirtualBox *virtualbox)
 {
     SCDynamicStoreContext ctx;
     RT_ZERO(ctx);
@@ -106,7 +106,7 @@ HRESULT HostDnsServiceDarwin::init()
     m->m_Stopper = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx);
     AssertReturn(m->m_Stopper, E_FAIL);
 
-    HRESULT hrc = HostDnsMonitor::init();
+    HRESULT hrc = HostDnsMonitor::init(virtualbox);
     AssertComRCReturn(hrc, hrc);
 
     return updateInfo();
@@ -115,7 +115,7 @@ HRESULT HostDnsServiceDarwin::init()
 
 void HostDnsServiceDarwin::monitorThreadShutdown()
 {
-    ALock l(this);
+    RTCLock grab(m_LockMtx);
     if (!m->m_fStop)
     {
         CFRunLoopSourceSignal(m->m_Stopper);
diff --git a/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp b/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp
index edcdd60..a6511b6 100644
--- a/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp
+++ b/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp
@@ -38,6 +38,7 @@
 # include <sys/types.h>
 # include <sys/stat.h>
 # include <unistd.h>
+# include <stdio.h>
 # include <sys/ioctl.h>
 # include <fcntl.h>
 # include <cam/cam.h>
diff --git a/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp b/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp
index d738e57..da509e3 100644
--- a/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp
+++ b/src/VBox/Main/src-server/freebsd/USBProxyServiceFreeBSD.cpp
@@ -114,12 +114,12 @@ int USBProxyServiceFreeBSD::captureDevice(HostUSBDevice *aDevice)
     AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
 
     AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
-    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
+    LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
 
     /*
      * Don't think we need to do anything when the device is held... fake it.
      */
-    Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
+    Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_Capturing);
     devLock.release();
     interruptWait();
 
@@ -133,12 +133,12 @@ int USBProxyServiceFreeBSD::releaseDevice(HostUSBDevice *aDevice)
     AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
 
     AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
-    LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
+    LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
 
     /*
      * We're not really holding it atm., just fake it.
      */
-    Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
+    Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_ReleasingToHost);
     devLock.release();
     interruptWait();
 
diff --git a/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
index 5f4bd13..92fe0ea 100644
--- a/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
+++ b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
@@ -34,15 +34,18 @@
 struct HostDnsServiceWin::Data
 {
     HKEY hKeyTcpipParameters;
+    bool fTimerArmed;
 
 #define DATA_SHUTDOWN_EVENT   0
 #define DATA_DNS_UPDATE_EVENT 1
-#define DATA_MAX_EVENT        2
+#define DATA_TIMER            2
+#define DATA_MAX_EVENT        3
     HANDLE haDataEvent[DATA_MAX_EVENT];
 
     Data()
     {
         hKeyTcpipParameters = NULL;
+        fTimerArmed = false;
 
         for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
             haDataEvent[i] = NULL;
@@ -80,12 +83,20 @@ HostDnsServiceWin::HostDnsServiceWin()
 
     for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
     {
-        data->haDataEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
-        if (data->haDataEvent[i] == NULL)
+        HANDLE h;
+
+        if (i ==  DATA_TIMER)
+            h = CreateWaitableTimer(NULL, FALSE, NULL);
+        else
+            h = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+        if (h == NULL)
         {
             LogRel(("HostDnsServiceWin: failed to create event (error %d)\n", GetLastError()));
             return;
         }
+
+        data->haDataEvent[i] = h;
     }
 
     m = data.release();
@@ -99,12 +110,12 @@ HostDnsServiceWin::~HostDnsServiceWin()
 }
 
 
-HRESULT HostDnsServiceWin::init()
+HRESULT HostDnsServiceWin::init(VirtualBox *virtualbox)
 {
     if (m == NULL)
         return E_FAIL;
 
-    HRESULT hrc = HostDnsMonitor::init();
+    HRESULT hrc = HostDnsMonitor::init(virtualbox);
     if (FAILED(hrc))
         return hrc;
 
@@ -155,19 +166,45 @@ int HostDnsServiceWin::monitorWorker()
 
         if (dwReady == WAIT_OBJECT_0 + DATA_DNS_UPDATE_EVENT)
         {
-            updateInfo();
+            /*
+             * Registry updates for multiple values are not atomic, so
+             * wait a bit to avoid racing and reading partial update.
+             */
+            if (!m->fTimerArmed)
+            {
+                LARGE_INTEGER delay; /* in 100ns units */
+                delay.QuadPart = -2 * 1000 * 1000 * 10LL; /* relative: 2s */
+
+                BOOL ok = SetWaitableTimer(m->haDataEvent[DATA_TIMER], &delay,
+                                           0, NULL, NULL, TRUE);
+                if (ok)
+                {
+                    m->fTimerArmed = true;
+                }
+                else
+                {
+                    LogRel(("HostDnsServiceWin: failed to arm timer (error %d)\n", GetLastError()));
+                    updateInfo();
+                }
+            }
 
             ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
             registerNotification(m->hKeyTcpipParameters,
                                  m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
-
+        }
+        else if (dwReady == WAIT_OBJECT_0 + DATA_TIMER)
+        {
+            m->fTimerArmed = false;
+            updateInfo();
+        }
+        else if (dwReady == WAIT_FAILED)
+        {
+            LogRel(("HostDnsServiceWin: WaitForMultipleObjects failed: error %d\n", GetLastError()));
+            return VERR_INTERNAL_ERROR;
         }
         else
         {
-            if (dwReady == WAIT_FAILED)
-                LogRel(("HostDnsServiceWin: WaitForMultipleObjects failed: error %d\n", GetLastError()));
-            else
-                LogRel(("HostDnsServiceWin: WaitForMultipleObjects unexpected return value %d\n", dwReady));
+            LogRel(("HostDnsServiceWin: WaitForMultipleObjects unexpected return value %d\n", dwReady));
             return VERR_INTERNAL_ERROR;
         }
     }
diff --git a/src/VBox/Main/xml/Settings.cpp b/src/VBox/Main/xml/Settings.cpp
index 62a4bae..a603c50 100644
--- a/src/VBox/Main/xml/Settings.cpp
+++ b/src/VBox/Main/xml/Settings.cpp
@@ -2564,6 +2564,8 @@ void MachineConfigFile::readSerialPorts(const xml::ElementNode &elmUART,
             port.portMode = PortMode_HostDevice;
         else if (strPortMode == "Disconnected")
             port.portMode = PortMode_Disconnected;
+        else if (strPortMode == "TCP")
+            port.portMode = PortMode_TCP;
         else
             throw ConfigFileError(this, pelmPort, N_("Invalid value '%s' in UART/Port/@hostMode attribute"), strPortMode.c_str());
 
@@ -4646,11 +4648,13 @@ void MachineConfigFile::buildHardwareXML(xml::ElementNode &elmParent,
         {
             case PortMode_HostPipe: pcszHostMode = "HostPipe"; break;
             case PortMode_HostDevice: pcszHostMode = "HostDevice"; break;
+            case PortMode_TCP: pcszHostMode = "TCP"; break;
             case PortMode_RawFile: pcszHostMode = "RawFile"; break;
             default: /*case PortMode_Disconnected:*/ pcszHostMode = "Disconnected"; break;
         }
         switch (port.portMode)
         {
+            case PortMode_TCP:
             case PortMode_HostPipe:
                 pelmPort->setAttribute("server", port.fServer);
                 /* no break */
@@ -5492,6 +5496,9 @@ void MachineConfigFile::bumpSettingsVersionIfNeeded()
 {
     if (m->sv < SettingsVersion_v1_15)
     {
+        // VirtualBox 5.0 adds paravirt providers, explicit AHCI port hotplug
+        // setting, USB storage controller, xHCI and serial port TCP backend.
+
         /*
          * Check whether a paravirtualization provider other than "Legacy" is used, if so bump the version.
          */
@@ -5503,14 +5510,20 @@ void MachineConfigFile::bumpSettingsVersionIfNeeded()
              * Check whether the hotpluggable flag of all storage devices differs
              * from the default for old settings.
              * AHCI ports are hotpluggable by default every other device is not.
+             * Also check if there are USB storage controllers.
              */
             for (StorageControllersList::const_iterator it = storageMachine.llStorageControllers.begin();
                  it != storageMachine.llStorageControllers.end();
                  ++it)
             {
-                bool fSettingsBumped = false;
                 const StorageController &sctl = *it;
 
+                if (sctl.controllerType == StorageControllerType_USB)
+                {
+                    m->sv = SettingsVersion_v1_15;
+                    return;
+                }
+
                 for (AttachedDevicesList::const_iterator it2 = sctl.llAttachedDevices.begin();
                      it2 != sctl.llAttachedDevices.end();
                      ++it2)
@@ -5523,14 +5536,39 @@ void MachineConfigFile::bumpSettingsVersionIfNeeded()
                             && sctl.controllerType == StorageControllerType_IntelAhci))
                     {
                         m->sv = SettingsVersion_v1_15;
-                        fSettingsBumped = true;
-                        break;
+                        return;
                     }
                 }
+            }
 
-                /* Abort early if possible. */
-                if (fSettingsBumped)
-                    break;
+            /*
+             * Check if there is an xHCI (USB3) USB controller.
+             */
+            for (USBControllerList::const_iterator it = hardwareMachine.usbSettings.llUSBControllers.begin();
+                 it != hardwareMachine.usbSettings.llUSBControllers.end();
+                 ++it)
+            {
+                const USBController &ctrl = *it;
+                if (ctrl.enmType == USBControllerType_XHCI)
+                {
+                    m->sv = SettingsVersion_v1_15;
+                    return;
+                }
+            }
+
+            /*
+             * Check if any serial port uses the TCP backend.
+             */
+            for (SerialPortsList::const_iterator it = hardwareMachine.llSerialPorts.begin();
+                 it != hardwareMachine.llSerialPorts.end();
+                 ++it)
+            {
+                const SerialPort &port = *it;
+                if (port.portMode == PortMode_TCP)
+                {
+                    m->sv = SettingsVersion_v1_15;
+                    return;
+                }
             }
         }
     }
diff --git a/src/VBox/Main/xml/VirtualBox-settings.xsd b/src/VBox/Main/xml/VirtualBox-settings.xsd
index dc393df..77bab82 100644
--- a/src/VBox/Main/xml/VirtualBox-settings.xsd
+++ b/src/VBox/Main/xml/VirtualBox-settings.xsd
@@ -6,7 +6,7 @@
  *  Oracle VM VirtualBox Settings Schema
  *  Common definitions
 
-    Copyright (C) 2004-2013 Oracle Corporation
+    Copyright (C) 2004-2015 Oracle Corporation
 
     This file is part of VirtualBox Open Source Edition (OSE), as
     available from http://www.virtualbox.org. This file is free software;
@@ -241,6 +241,7 @@
     <xsd:enumeration value="RawFile"/>
     <xsd:enumeration value="HostPipe"/>
     <xsd:enumeration value="HostDevice"/>
+    <xsd:enumeration value="TCP"/>
   </xsd:restriction>
 </xsd:simpleType>
 
diff --git a/src/VBox/RDP/client/COPYING b/src/VBox/RDP/client-1.8.3/COPYING
similarity index 100%
rename from src/VBox/RDP/client/COPYING
rename to src/VBox/RDP/client-1.8.3/COPYING
diff --git a/src/VBox/RDP/client/Makefile.in b/src/VBox/RDP/client-1.8.3/Makefile.in
similarity index 69%
rename from src/VBox/RDP/client/Makefile.in
rename to src/VBox/RDP/client-1.8.3/Makefile.in
index 5d0a94f..72dcf95 100644
--- a/src/VBox/RDP/client/Makefile.in
+++ b/src/VBox/RDP/client-1.8.3/Makefile.in
@@ -27,19 +27,20 @@ LDVNC       = @LDVNC@
 VNCLINK     = @VNCLINK@
 SOUNDOBJ    = @SOUNDOBJ@
 SCARDOBJ    = @SCARDOBJ@
+CREDSSPOBJ  = @CREDSSPOBJ@
 
-RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o Runtime/common/alloc/alloc.o Runtime/common/err/errmsg.o Runtime/common/err/errmsgxpcom.o Runtime/common/err/RTErrConvertFromErrno.o Runtime/common/err/RTErrConvertToErrno.o Runtime/common/misc/sg.o Runtime/common/path/RTPathAppend.o Runtime/common/path/RTPathAppendEx.o Runtime/common/path/ [...]
-X11OBJ   = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
+RDPOBJ   = tcp.o asn.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o utils.o Runtime/common/alloc/alloc.o Runtime/common/err/errmsg.o Runtime/common/err/errmsgxpcom.o Runtime/common/err/RTErrConvertFromErrno.o Runtime/common/err/RTErrConvertToErrno.o Runtime/common/misc/sg.o Runtime/common/path/RTPathAppend.o Runtime/common/path/RTPathAppendEx.o Runtim [...]
+X11OBJ   = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o ctrl.o
 VNCOBJ   = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
 
 .PHONY: all
 all: $(TARGETS)
 
-rdesktop: $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ)
-	$(CXX) $(CFLAGS) -o rdesktop $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ) $(LDFLAGS) -lX11
+rdesktop: $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ) $(CREDSSPOBJ)
+	$(CXX) $(CFLAGS) -o rdesktop $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ) $(CREDSSPOBJ) $(LDFLAGS) -lX11
 
-rdp2vnc: $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ) 
-	$(VNCLINK) $(CFLAGS) -o rdp2vnc $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ) $(LDFLAGS) $(LDVNC)
+rdp2vnc: $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ) $(CREDSSPOBJ)
+	$(VNCLINK) $(CFLAGS) -o rdp2vnc $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ) $(SCARDOBJ) $(CREDSSPOBJ) $(LDFLAGS) $(LDVNC)
 
 vnc/rdp2vnc.o: rdesktop.c
 	$(CC) $(CFLAGS) $(VNCINC) -DRDP2VNC -o vnc/rdp2vnc.o -c rdesktop.c
diff --git a/src/VBox/RDP/client/Makefile.kmk b/src/VBox/RDP/client-1.8.3/Makefile.kmk
similarity index 98%
rename from src/VBox/RDP/client/Makefile.kmk
rename to src/VBox/RDP/client-1.8.3/Makefile.kmk
index f823c85..2cb89a2 100644
--- a/src/VBox/RDP/client/Makefile.kmk
+++ b/src/VBox/RDP/client-1.8.3/Makefile.kmk
@@ -24,7 +24,7 @@ VBOX_PATH_DEVICES_USB  := $(PATH_ROOT)/src/VBox/Devices/USB
 VBOX_PATH_USB_LIB      := $(PATH_ROOT)/src/VBox/HostDrivers/VBoxUSB
 VBOX_PATH_MAIN_LINUX   := $(PATH_ROOT)/src/VBox/Main/src-server/linux
 VBOX_PATH_MAIN_INCLUDE := $(PATH_ROOT)/src/VBox/Main/include
-VBOX_RDESKTOP_SRC_SUBDIR = rdesktop-1.7.0-vrdp
+VBOX_RDESKTOP_SRC_SUBDIR = rdesktop-1.8.3-vrdp
 
 #
 # The rdesktop-vrdp program.
@@ -33,8 +33,8 @@ PROGRAMS += rdesktop-vrdp
 rdesktop-vrdp_TEMPLATE = VBOXR3NPEXE
 rdesktop-vrdp_SDKS = VBOX_OPENSSL2
 rdesktop-vrdp_DEFS = \
-	PACKAGE_NAME=\"rdesktop-vrdp\" PACKAGE_TARNAME=\"rdesktop-vrdp\" PACKAGE_VERSION=\"1.7.0\" \
-	PACKAGE_STRING=\"rdesktop\ 1.7.0\" PACKAGE_BUGREPORT=\"\" STDC_HEADERS=1 L_ENDIAN=1 \
+	PACKAGE_NAME=\"rdesktop-vrdp\" PACKAGE_TARNAME=\"rdesktop-vrdp\" PACKAGE_VERSION=\"1.8.3\" \
+	PACKAGE_STRING=\"rdesktop\ 1.8.3\" PACKAGE_BUGREPORT=\"\" STDC_HEADERS=1 L_ENDIAN=1 \
 	HAVE_SYS_TYPES_H=1 HAVE_SYS_STAT_H=1 HAVE_STDLIB_H=1 HAVE_STRING_H=1 HAVE_MEMORY_H=1 \
 	HAVE_STRINGS_H=1 HAVE_INTTYPES_H=1 HAVE_STDINT_H=1 HAVE_UNISTD_H=1 HAVE_SYS_SELECT_H=1 \
 	HAVE_LOCALE_H=1 HAVE_LANGINFO_H=1 HAVE_ICONV_H=1 \
@@ -67,6 +67,7 @@ rdesktop-vrdp_DEFS.freebsd = \
 
 rdesktop-vrdp_SOURCES = \
 	tcp.c \
+	asn.c \
 	iso.c \
 	mcs.c \
 	secure.c \
@@ -88,12 +89,14 @@ rdesktop-vrdp_SOURCES = \
 	lspci.c \
 	seamless.c \
 	ssl.c \
+	utils.c \
 	rdesktop.c \
 	xwin.c \
 	xkeymap.c \
 	ewmhints.c \
 	xclip.c \
 	cliprdr.c \
+	ctrl.c \
 	rdpsnd.c \
 	rdpsnd_dsp.c
 rdesktop-vrdp_SOURCES.linux = \
@@ -121,6 +124,8 @@ rdesktop-vrdp_LIBS = \
 	$(LIB_RUNTIME)
 rdesktop-vrdp_LIBS.solaris = \
 	nsl
+rdesktop-vrdp_LIBS.freebsd = \
+	iconv
 
 #
 # The keymaps.
@@ -148,6 +153,7 @@ rdesktop-src_EXEC_SOURCES = \
 	install-sh \
 	keymaps/convert-map=>keymaps/convert-map
 rdesktop-src_SOURCES = \
+	asn.c=>asn.c \
 	bitmap.c=>bitmap.c \
 	cache.c=>cache.c \
 	channels.c=>channels.c \
@@ -155,6 +161,7 @@ rdesktop-src_SOURCES = \
 	configure.ac=>configure.ac \
 	constants.h=>constants.h \
 	COPYING=>COPYING \
+	cssp.c=>cssp.c \
 	disk.c=>disk.c \
 	disk.h=>disk.h \
 	doc/TODO=>doc/TODO \
@@ -230,12 +237,12 @@ rdesktop-src_SOURCES = \
 	rdp5.c=>rdp5.c \
 	rdp.c=>rdp.c \
 	rdpdr.c=>rdpdr.c \
-	rdpsnd_alsa.c=>rdpsnd_alsa.c \
 	rdpsnd.c=>rdpsnd.c \
 	rdpsnd_dsp.c=>rdpsnd_dsp.c \
 	rdpsnd_dsp.h=>rdpsnd_dsp.h \
 	rdpsnd.h=>rdpsnd.h \
 	rdpsnd_libao.c=>rdpsnd_libao.c \
+	rdpsnd_alsa.c=>rdpsnd_alsa.c \
 	rdpsnd_oss.c=>rdpsnd_oss.c \
 	rdpsnd_sgi.c=>rdpsnd_sgi.c \
 	rdpsnd_sun.c=>rdpsnd_sun.c \
@@ -251,9 +258,11 @@ rdesktop-src_SOURCES = \
 	ssl.h=>ssl.h \
 	tcp.c=>tcp.c \
 	types.h=>types.h \
+	utils.c=>utils.c \
 	vrdp/vrdpusb.h=>vrdp/vrdpusb.h \
 	vrdp/rdpusb.c=>vrdp/rdpusb.c \
 	xclip.c=>xclip.c \
+	ctrl.c=>ctrl.c \
 	xkeymap.c=>xkeymap.c \
 	xproto.h=>xproto.h \
 	xwin.c=>xwin.c \
diff --git a/src/VBox/RDP/client/README b/src/VBox/RDP/client-1.8.3/README
similarity index 100%
rename from src/VBox/RDP/client/README
rename to src/VBox/RDP/client-1.8.3/README
diff --git a/src/VBox/RDP/client-1.8.3/asn.c b/src/VBox/RDP/client-1.8.3/asn.c
new file mode 100644
index 0000000..69c6757
--- /dev/null
+++ b/src/VBox/RDP/client-1.8.3/asn.c
@@ -0,0 +1,118 @@
+/* -*- c-basic-offset: 8 -*-
+   rdesktop: A Remote Desktop Protocol client.
+   ASN.1 utility functions
+   Copyright 2012 Henrik Andersson <hean01 at cendio.se> for Cendio AB
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the General Public License version 2 (GPLv2) at this time for any software where
+ * a choice of GPL license versions is made available with the language indicating
+ * that GPLv2 or any later version may be used, or where a choice of which version
+ * of the GPL is applied is otherwise unspecified.
+ */
+
+#include "rdesktop.h"
+
+
+/* Parse an ASN.1 BER header */
+RD_BOOL
+ber_parse_header(STREAM s, int tagval, int *length)
+{
+	int tag, len;
+
+	if (tagval > 0xff)
+	{
+		in_uint16_be(s, tag);
+	}
+	else
+	{
+		in_uint8(s, tag);
+	}
+
+	if (tag != tagval)
+	{
+		error("expected tag %d, got %d\n", tagval, tag);
+		return False;
+	}
+
+	in_uint8(s, len);
+
+	if (len & 0x80)
+	{
+		len &= ~0x80;
+		*length = 0;
+		while (len--)
+			next_be(s, *length);
+	}
+	else
+		*length = len;
+
+	return s_check(s);
+}
+
+/* Output an ASN.1 BER header */
+void
+ber_out_header(STREAM s, int tagval, int length)
+{
+	if (tagval > 0xff)
+	{
+		out_uint16_be(s, tagval);
+	}
+	else
+	{
+		out_uint8(s, tagval);
+	}
+
+	if (length >= 0x80)
+	{
+		out_uint8(s, 0x82);
+		out_uint16_be(s, length);
+	}
+	else
+		out_uint8(s, length);
+}
+
+/* Output an ASN.1 BER integer */
+void
+ber_out_integer(STREAM s, int value)
+{
+	ber_out_header(s, BER_TAG_INTEGER, 2);
+	out_uint16_be(s, value);
+}
+
+RD_BOOL
+ber_in_header(STREAM s, int *tagval, int *decoded_len)
+{
+	in_uint8(s, *tagval);
+	in_uint8(s, *decoded_len);
+
+	if (*decoded_len < 0x80)
+		return True;
+	else if (*decoded_len == 0x81)
+	{
+		in_uint8(s, *decoded_len);
+		return True;
+	}
+	else if (*decoded_len == 0x82)
+	{
+		in_uint16_be(s, *decoded_len);
+		return True;
+	}
+
+	return False;
+}
diff --git a/src/VBox/RDP/client/bitmap.c b/src/VBox/RDP/client-1.8.3/bitmap.c
similarity index 100%
rename from src/VBox/RDP/client/bitmap.c
rename to src/VBox/RDP/client-1.8.3/bitmap.c
diff --git a/src/VBox/RDP/client/bootstrap b/src/VBox/RDP/client-1.8.3/bootstrap
similarity index 100%
rename from src/VBox/RDP/client/bootstrap
rename to src/VBox/RDP/client-1.8.3/bootstrap
diff --git a/src/VBox/RDP/client/cache.c b/src/VBox/RDP/client-1.8.3/cache.c
similarity index 100%
rename from src/VBox/RDP/client/cache.c
rename to src/VBox/RDP/client-1.8.3/cache.c
diff --git a/src/VBox/RDP/client/channels.c b/src/VBox/RDP/client-1.8.3/channels.c
similarity index 97%
rename from src/VBox/RDP/client/channels.c
rename to src/VBox/RDP/client-1.8.3/channels.c
index 1a6e1a3..5a704e4 100644
--- a/src/VBox/RDP/client/channels.c
+++ b/src/VBox/RDP/client-1.8.3/channels.c
@@ -1,7 +1,7 @@
 /* -*- c-basic-offset: 8 -*-
    rdesktop: A Remote Desktop Protocol client.
    Protocol services - Virtual channels
-   Copyright (C) Erik Forsberg <forsberg at cendio.se> 2003
+   Copyright 2003 Erik Forsberg <forsberg at cendio.se> for Cendio AB
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
 
    This program is free software: you can redistribute it and/or modify
@@ -35,7 +35,7 @@
 #define CHANNEL_FLAG_LAST		0x02
 #define CHANNEL_FLAG_SHOW_PROTOCOL	0x10
 
-extern RD_BOOL g_use_rdp5;
+extern RDP_VERSION g_rdp_version;
 extern RD_BOOL g_encryption;
 
 VCHANNEL g_channels[MAX_CHANNELS];
@@ -56,7 +56,7 @@ channel_register(char *name, uint32 flags, void (*callback) (STREAM))
 {
 	VCHANNEL *channel;
 
-	if (!g_use_rdp5)
+	if (g_rdp_version < RDP_V5)
 		return NULL;
 
 	if (g_num_channels >= MAX_CHANNELS)
diff --git a/src/VBox/RDP/client/cliprdr.c b/src/VBox/RDP/client-1.8.3/cliprdr.c
similarity index 98%
rename from src/VBox/RDP/client/cliprdr.c
rename to src/VBox/RDP/client-1.8.3/cliprdr.c
index cbe478b..e6f19ee 100644
--- a/src/VBox/RDP/client/cliprdr.c
+++ b/src/VBox/RDP/client-1.8.3/cliprdr.c
@@ -1,7 +1,7 @@
 /* -*- c-basic-offset: 8 -*-
    rdesktop: A Remote Desktop Protocol client.
    Protocol services - Clipboard functions
-   Copyright (C) Erik Forsberg <forsberg at cendio.se> 2003
+   Copyright 2003 Erik Forsberg <forsberg at cendio.se> for Cendio AB
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
 
    This program is free software: you can redistribute it and/or modify
diff --git a/src/VBox/RDP/client/config.guess b/src/VBox/RDP/client-1.8.3/config.guess
similarity index 100%
rename from src/VBox/RDP/client/config.guess
rename to src/VBox/RDP/client-1.8.3/config.guess
diff --git a/src/VBox/RDP/client/config.sub b/src/VBox/RDP/client-1.8.3/config.sub
similarity index 100%
rename from src/VBox/RDP/client/config.sub
rename to src/VBox/RDP/client-1.8.3/config.sub
diff --git a/src/VBox/RDP/client/configure b/src/VBox/RDP/client-1.8.3/configure
similarity index 88%
rename from src/VBox/RDP/client/configure
rename to src/VBox/RDP/client-1.8.3/configure
index 4b93bef..5d40177 100755
--- a/src/VBox/RDP/client/configure
+++ b/src/VBox/RDP/client-1.8.3/configure
@@ -1,11 +1,9 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for rdesktop 1.7.0.
+# Generated by GNU Autoconf 2.69 for rdesktop 1.8.3.
 #
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -134,6 +132,31 @@ export LANGUAGE
 # CDPATH.
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
   as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
@@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
 else
   exitcode=1; echo positional parameters were not saved.
 fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -212,21 +236,25 @@ IFS=$as_save_IFS
 
 
       if test "x$CONFIG_SHELL" != x; then :
-  # We cannot yet assume a decent shell, so we have to provide a
-	# neutralization value for shells without unset; and this also
-	# works around shells that cannot unset nonexistent variables.
-	# Preserve -v and -x to the replacement shell.
-	BASH_ENV=/dev/null
-	ENV=/dev/null
-	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-	export CONFIG_SHELL
-	case $- in # ((((
-	  *v*x* | *x*v* ) as_opts=-vx ;;
-	  *v* ) as_opts=-v ;;
-	  *x* ) as_opts=-x ;;
-	  * ) as_opts= ;;
-	esac
-	exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
 fi
 
     if test x$as_have_required = xno; then :
@@ -328,6 +356,14 @@ $as_echo X"$as_dir" |
 
 
 } # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -449,6 +485,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
   chmod +x "$as_me.lineno" ||
     { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
   # original and so on.  Autoconf is especially sensitive to this).
@@ -483,16 +523,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -504,28 +544,8 @@ else
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-	test -d "$1/.";
-      else
-	case $1 in #(
-	-*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -557,8 +577,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='rdesktop'
 PACKAGE_TARNAME='rdesktop'
-PACKAGE_VERSION='1.7.0'
-PACKAGE_STRING='rdesktop 1.7.0'
+PACKAGE_VERSION='1.8.3'
+PACKAGE_STRING='rdesktop 1.8.3'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -600,22 +620,29 @@ ac_includes_default="\
 #endif"
 
 ac_subst_vars='LTLIBOBJS
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
 LIBICONV
 LIBOBJS
 SOUNDOBJ
+LIBSAMPLERATE_LIBS
+LIBSAMPLERATE_CFLAGS
+ALSA_LIBS
+ALSA_CFLAGS
+LIBAO_LIBS
+LIBAO_CFLAGS
 RDP2VNCTARGET
 VNCLINK
 LDVNC
 VNCINC
 SCARDOBJ
+PCSCLITE_LIBS
+PCSCLITE_CFLAGS
+XRANDR_LIBS
+XRANDR_CFLAGS
+CREDSSPOBJ
+GSSGLUE_LIBS
+GSSGLUE_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
 ssldir
 STRIP
 PKG_CONFIG
@@ -640,6 +667,14 @@ CPPFLAGS
 LDFLAGS
 CFLAGS
 CC
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
 target_alias
 host_alias
 build_alias
@@ -684,6 +719,8 @@ enable_option_checking
 with_x
 with_openssl
 enable_static_openssl
+enable_credssp
+enable_static_gssglue
 enable_smartcard
 with_egd_socket
 with_libvncserver_config
@@ -701,6 +738,7 @@ with_debug_sound
 with_debug_channel
 with_debug_seamless
 with_debug_smartcard
+with_debug_credssp
 '
       ac_precious_vars='build_alias
 host_alias
@@ -714,7 +752,22 @@ CXX
 CXXFLAGS
 CCC
 CPP
-XMKMF'
+XMKMF
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+GSSGLUE_CFLAGS
+GSSGLUE_LIBS
+XRANDR_CFLAGS
+XRANDR_LIBS
+PCSCLITE_CFLAGS
+PCSCLITE_LIBS
+LIBAO_CFLAGS
+LIBAO_LIBS
+ALSA_CFLAGS
+ALSA_LIBS
+LIBSAMPLERATE_CFLAGS
+LIBSAMPLERATE_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1170,8 +1223,6 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used" >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1257,7 +1308,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures rdesktop 1.7.0 to adapt to many kinds of systems.
+\`configure' configures rdesktop 1.8.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1326,7 +1377,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of rdesktop 1.7.0:";;
+     short | recursive ) echo "Configuration of rdesktop 1.8.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1335,8 +1386,9 @@ Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --enable-static-openssl link OpenSSL statically
-  --enable-smartcard	  Enables smart-card support.
-
+  --disable-credssp       disable support for CredSSP
+  --enable-static-gssglue
+  --disable-smartcard     disable support for smartcard
   --enable-static-libsamplerate link libsamplerate statically
   --disable-largefile     omit support for large files
 
@@ -1359,6 +1411,7 @@ Optional Packages:
   --with-debug-channel  enable debugging of virtual channel code
   --with-debug-seamless  enable debugging of SeamlessRDP code
   --with-debug-smartcard  enable debugging of smart-card code
+  --with-debug-credssp	enable debugging of CredSSP code
 
 Some influential environment variables:
   CC          C compiler command
@@ -1372,6 +1425,31 @@ Some influential environment variables:
   CXXFLAGS    C++ compiler flags
   CPP         C preprocessor
   XMKMF       Path to xmkmf, Makefile generator for X Window System
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
+  GSSGLUE_CFLAGS
+              C compiler flags for GSSGLUE, overriding pkg-config
+  GSSGLUE_LIBS
+              linker flags for GSSGLUE, overriding pkg-config
+  XRANDR_CFLAGS
+              C compiler flags for XRANDR, overriding pkg-config
+  XRANDR_LIBS linker flags for XRANDR, overriding pkg-config
+  PCSCLITE_CFLAGS
+              C compiler flags for PCSCLITE, overriding pkg-config
+  PCSCLITE_LIBS
+              linker flags for PCSCLITE, overriding pkg-config
+  LIBAO_CFLAGS
+              C compiler flags for LIBAO, overriding pkg-config
+  LIBAO_LIBS  linker flags for LIBAO, overriding pkg-config
+  ALSA_CFLAGS C compiler flags for ALSA, overriding pkg-config
+  ALSA_LIBS   linker flags for ALSA, overriding pkg-config
+  LIBSAMPLERATE_CFLAGS
+              C compiler flags for LIBSAMPLERATE, overriding pkg-config
+  LIBSAMPLERATE_LIBS
+              linker flags for LIBSAMPLERATE, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -1439,10 +1517,10 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-rdesktop configure 1.7.0
-generated by GNU Autoconf 2.68
+rdesktop configure 1.8.3
+generated by GNU Autoconf 2.69
 
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1666,7 +1744,7 @@ $as_echo "$ac_try_echo"; } >&5
 	 test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
 	 test "$cross_compiling" = yes ||
-	 $as_test_x conftest$ac_exeext
+	 test -x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
@@ -1999,8 +2077,8 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by rdesktop $as_me 1.7.0, which was
-generated by GNU Autoconf 2.68.  Invocation command line was
+It was created by rdesktop $as_me 1.8.3, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
 
@@ -2350,6 +2428,107 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2372,7 +2551,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -2412,7 +2591,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -2465,7 +2644,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -2506,7 +2685,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
@@ -2564,7 +2743,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -2608,7 +2787,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3054,8 +3233,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdarg.h>
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -3171,7 +3349,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3215,7 +3393,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CXX="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3401,35 +3579,6 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
-
-
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
@@ -3467,7 +3616,7 @@ case $as_dir/ in #((
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
 	  if test $ac_prog = install &&
 	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
@@ -3684,7 +3833,7 @@ do
     for ac_prog in grep ggrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+      as_fn_executable_p "$ac_path_GREP" || continue
 # Check for GNU ac_path_GREP and select it if it is found.
   # Check for GNU $ac_path_GREP
 case `"$ac_path_GREP" --version 2>&1` in
@@ -3750,7 +3899,7 @@ do
     for ac_prog in egrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+      as_fn_executable_p "$ac_path_EGREP" || continue
 # Check for GNU ac_path_EGREP and select it if it is found.
   # Check for GNU $ac_path_EGREP
 case `"$ac_path_EGREP" --version 2>&1` in
@@ -4848,8 +4997,9 @@ if test "$no_x" = "yes"; then
     exit 1
 fi
 
-# Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; ac_word=$2
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
 if ${ac_cv_path_PKG_CONFIG+:} false; then :
@@ -4866,7 +5016,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4888,6 +5038,63 @@ $as_echo "no" >&6; }
 fi
 
 
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
 $as_echo_n "checking for library containing socket... " >&6; }
@@ -5125,7 +5332,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5165,7 +5372,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_STRIP="strip"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5203,11 +5410,6 @@ fi
 
 
 
-
-
-
-rpath=""
-
 #
 # OpenSSL detection borrowed from stunnel
 #
@@ -5262,103 +5464,547 @@ _ACEOF
 CFLAGS="$CFLAGS -I$ssldir/include"
 # Check whether --enable-static-openssl was given.
 if test "${enable_static_openssl+set}" = set; then :
-  enableval=$enable_static_openssl;
-LIBS="$LIBS $ssldir/lib/libcrypto.a"
-
+  enableval=$enable_static_openssl; static_openssl=yes
 else
-
-LIBS="$LIBS -L$ssldir/lib -lcrypto"
-rpath="$rpath:$ssldir/lib"
-
-fi
-
-# xrandr
-if test -n "$PKG_CONFIG"; then
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config not available, cannot check for xrandr" >&5
-$as_echo "$as_me: WARNING: pkg-config not available, cannot check for xrandr" >&2;}
-			HAVE_XRANDR=0
-
-fi
-if test x"$HAVE_XRANDR" = "x1"; then
-    CFLAGS="$CFLAGS $XRANDR_CFLAGS"
-    LIBS="$LIBS $XRANDR_LIBS"
-    $as_echo "#define HAVE_XRANDR 1" >>confdefs.h
-
+  static_openssl=no
 fi
 
-# Check whether --enable-smartcard was given.
-if test "${enable_smartcard+set}" = set; then :
-  enableval=$enable_smartcard;
-	     	case "$OSTYPE" in
-			darwin*)
-				ac_fn_c_check_header_mongrel "$LINENO" "PCSC/pcsclite.h" "ac_cv_header_PCSC_pcsclite_h" "$ac_includes_default"
-if test "x$ac_cv_header_PCSC_pcsclite_h" = xyes; then :
-  WITH_SCARD=1
+if test x"$static_openssl" = "xyes"; then
+    # OpenSSL generally relies on libz
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5
+$as_echo_n "checking for library containing deflate... " >&6; }
+if ${ac_cv_search_deflate+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  WITH_SCARD=0
-fi
-
-
-				PCSCLITE_CFLAGS=""
-				PCSCLITE_LIBS="-framework PCSC"
-				;;
-			*)
-				if test -n "$PKG_CONFIG"; then
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config not available, cannot check for libpcsclite" >&5
-$as_echo "$as_me: WARNING: pkg-config not available, cannot check for libpcsclite" >&2;}
-			WITH_SCARD=0
-
-				fi
-				;;
-		esac
-
-		if test x"$WITH_SCARD" = "x1"; then
-			SCARDOBJ="scard.o"
-			CFLAGS="$CFLAGS $PCSCLITE_CFLAGS"
-			LIBS="$LIBS $PCSCLITE_LIBS"
-			$as_echo "#define WITH_SCARD 1" >>confdefs.h
-
-		fi
-
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for old version of PCSC" >&5
-$as_echo_n "checking for old version of PCSC... " >&6; }
-		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-			#include <stdlib.h>
-			#ifdef __APPLE__
-			#include <PCSC/wintypes.h>
-			#include <PCSC/winscard.h>
-			#else
-			#include <winscard.h>
-			#endif
-
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char deflate ();
 int
 main ()
 {
-SCardControl(NULL, NULL, 0, NULL, NULL);
+return deflate ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-$as_echo "#define WITH_PCSC120 1" >>confdefs.h
+for ac_lib in '' z; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_deflate=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_deflate+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_deflate+:} false; then :
+
+else
+  ac_cv_search_deflate=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5
+$as_echo "$ac_cv_search_deflate" >&6; }
+ac_res=$ac_cv_search_deflate
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+    LIBS="-L$ssldir/lib -L$ssldir/lib64 -Wl,-Bstatic -lssl -lcrypto -Wl,-Bdynamic $LIBS"
+else
+    LIBS="-L$ssldir/lib -L$ssldir/lib64 -lssl -lcrypto $LIBS"
+
+    #
+    # target-specific stuff
+    #
+    case "$host" in
+    *-*-solaris*)
+        LDFLAGS="$LDFLAGS -R$ssldir/lib"
+        ;;
+    *-dec-osf*)
+        LDFLAGS="$LDFLAGS -Wl,-rpath,$ssldir/lib"
+        ;;
+    esac
+fi
+
+# Check whether --enable-credssp was given.
+if test "${enable_credssp+set}" = set; then :
+  enableval=$enable_credssp;
+fi
+
+# Check whether --enable-static-gssglue was given.
+if test "${enable_static_gssglue+set}" = set; then :
+  enableval=$enable_static_gssglue; static_gssglue=yes
+else
+  static_gssglue=no
+fi
+
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
+fi
+
 
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+fi
+if test "x$enable_credssp" != "xno"; then :
+
+	  if test -n "$PKG_CONFIG"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSSGLUE" >&5
+$as_echo_n "checking for GSSGLUE... " >&6; }
+
+if test -n "$GSSGLUE_CFLAGS"; then
+    pkg_cv_GSSGLUE_CFLAGS="$GSSGLUE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libgssglue\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libgssglue") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_GSSGLUE_CFLAGS=`$PKG_CONFIG --cflags "libgssglue" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$GSSGLUE_LIBS"; then
+    pkg_cv_GSSGLUE_LIBS="$GSSGLUE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libgssglue\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libgssglue") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_GSSGLUE_LIBS=`$PKG_CONFIG --libs "libgssglue" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libgssglue" 2>&1`
+        else
+	        GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libgssglue" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$GSSGLUE_PKG_ERRORS" >&5
+
+	WITH_CREDSSP=0
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	WITH_CREDSSP=0
+else
+	GSSGLUE_CFLAGS=$pkg_cv_GSSGLUE_CFLAGS
+	GSSGLUE_LIBS=$pkg_cv_GSSGLUE_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	WITH_CREDSSP=1
+fi
+	  fi
+
+	  if test x"$WITH_CREDSSP" = "x1"; then
+	      CREDSSPOBJ="cssp.o"
+	      CFLAGS="$CFLAGS $GSSGLUE_CFLAGS"
+
+	      if test "x$static_gssglue" != "xno"; then :
+
+	          LIBS="$LIBS -Wl,-Bstatic -lgssglue -Wl,-Bdynamic"
+
+else
+
+	          LIBS="$LIBS -lgssglue"
+
+fi
+
+	      $as_echo "#define WITH_CREDSSP 1" >>confdefs.h
 
+	  else
+		echo
+		echo "CredSSP support requires libgssglue, install the dependency"
+		echo "or disable the feature using --disable-credssp."
+		echo
+		exit 1
+	  fi
+
+fi
+
+
+# xrandr
+if test -n "$PKG_CONFIG"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRANDR" >&5
+$as_echo_n "checking for XRANDR... " >&6; }
+
+if test -n "$XRANDR_CFLAGS"; then
+    pkg_cv_XRANDR_CFLAGS="$XRANDR_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xrandr\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "xrandr") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_XRANDR_CFLAGS=`$PKG_CONFIG --cflags "xrandr" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$XRANDR_LIBS"; then
+    pkg_cv_XRANDR_LIBS="$XRANDR_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xrandr\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "xrandr") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_XRANDR_LIBS=`$PKG_CONFIG --libs "xrandr" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        XRANDR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "xrandr" 2>&1`
+        else
+	        XRANDR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "xrandr" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$XRANDR_PKG_ERRORS" >&5
+
+	HAVE_XRANDR=0
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	HAVE_XRANDR=0
+else
+	XRANDR_CFLAGS=$pkg_cv_XRANDR_CFLAGS
+	XRANDR_LIBS=$pkg_cv_XRANDR_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	HAVE_XRANDR=1
+fi
 fi
+if test x"$HAVE_XRANDR" = "x1"; then
+    CFLAGS="$CFLAGS $XRANDR_CFLAGS"
+    LIBS="$LIBS $XRANDR_LIBS"
+    $as_echo "#define HAVE_XRANDR 1" >>confdefs.h
 
+fi
 
+# Check whether --enable-smartcard was given.
+if test "${enable_smartcard+set}" = set; then :
+  enableval=$enable_smartcard;
+fi
+
+if test "x$enable_smartcard" != "xno"; then :
+
+	case "$OSTYPE" in
+	     darwin*)
+		ac_fn_c_check_header_mongrel "$LINENO" "PCSC/pcsclite.h" "ac_cv_header_PCSC_pcsclite_h" "$ac_includes_default"
+if test "x$ac_cv_header_PCSC_pcsclite_h" = xyes; then :
+  WITH_SCARD=1
+else
+  WITH_SCARD=0
+fi
+
+
+		PCSCLITE_CFLAGS=""
+		PCSCLITE_LIBS="-framework PCSC"
+		;;
+	     *)
+		if test -n "$PKG_CONFIG"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PCSCLITE" >&5
+$as_echo_n "checking for PCSCLITE... " >&6; }
+
+if test -n "$PCSCLITE_CFLAGS"; then
+    pkg_cv_PCSCLITE_CFLAGS="$PCSCLITE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpcsclite\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libpcsclite") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_PCSCLITE_CFLAGS=`$PKG_CONFIG --cflags "libpcsclite" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$PCSCLITE_LIBS"; then
+    pkg_cv_PCSCLITE_LIBS="$PCSCLITE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpcsclite\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libpcsclite") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_PCSCLITE_LIBS=`$PKG_CONFIG --libs "libpcsclite" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        PCSCLITE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpcsclite" 2>&1`
+        else
+	        PCSCLITE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpcsclite" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$PCSCLITE_PKG_ERRORS" >&5
+
+	WITH_SCARD=0
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	WITH_SCARD=0
+else
+	PCSCLITE_CFLAGS=$pkg_cv_PCSCLITE_CFLAGS
+	PCSCLITE_LIBS=$pkg_cv_PCSCLITE_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	WITH_SCARD=1
+fi
+		fi
+		;;
+	esac
+
+	if test x"$WITH_SCARD" = "x1"; then
+	   SCARDOBJ="scard.o"
+	   CFLAGS="$CFLAGS $PCSCLITE_CFLAGS"
+	   LIBS="$LIBS $PCSCLITE_LIBS"
+	   $as_echo "#define WITH_SCARD 1" >>confdefs.h
+
+	else
+	   echo
+	   echo "SmartCard support requires PCSC, install the dependency"
+	   echo "or disable the feature using --disable-smartcard."
+	   echo
+	   exit 1
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for old version of PCSC" >&5
+$as_echo_n "checking for old version of PCSC... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+		#include <stdlib.h>
+		#ifdef __APPLE__
+		#include <PCSC/wintypes.h>
+		#include <PCSC/winscard.h>
+		#else
+		#include <winscard.h>
+		#endif
+
+int
+main ()
+{
+SCardControl(NULL, NULL, 0, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define WITH_PCSC120 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
 
 
 #
@@ -5528,28 +6174,226 @@ fi
 
 if test -n "$PKG_CONFIG"; then
 
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config not available, cannot check for ao" >&5
-$as_echo "$as_me: WARNING: pkg-config not available, cannot check for ao" >&2;}
-			HAVE_LIBAO=0
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBAO" >&5
+$as_echo_n "checking for LIBAO... " >&6; }
+
+if test -n "$LIBAO_CFLAGS"; then
+    pkg_cv_LIBAO_CFLAGS="$LIBAO_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ao\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ao") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBAO_CFLAGS=`$PKG_CONFIG --cflags "ao" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBAO_LIBS"; then
+    pkg_cv_LIBAO_LIBS="$LIBAO_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ao\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ao") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBAO_LIBS=`$PKG_CONFIG --libs "ao" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LIBAO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ao" 2>&1`
+        else
+	        LIBAO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ao" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LIBAO_PKG_ERRORS" >&5
+
+	HAVE_LIBAO=0
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	HAVE_LIBAO=0
+else
+	LIBAO_CFLAGS=$pkg_cv_LIBAO_CFLAGS
+	LIBAO_LIBS=$pkg_cv_LIBAO_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	HAVE_LIBAO=1
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ALSA" >&5
+$as_echo_n "checking for ALSA... " >&6; }
 
+if test -n "$ALSA_CFLAGS"; then
+    pkg_cv_ALSA_CFLAGS="$ALSA_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "alsa") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ALSA_CFLAGS=`$PKG_CONFIG --cflags "alsa" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ALSA_LIBS"; then
+    pkg_cv_ALSA_LIBS="$ALSA_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "alsa") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ALSA_LIBS=`$PKG_CONFIG --libs "alsa" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
 
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config not available, cannot check for alsa" >&5
-$as_echo "$as_me: WARNING: pkg-config not available, cannot check for alsa" >&2;}
-			HAVE_ALSA=0
 
 
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config not available, cannot check for samplerate" >&5
-$as_echo "$as_me: WARNING: pkg-config not available, cannot check for samplerate" >&2;}
-			HAVE_LIBSAMPLERATE=0
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        ALSA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "alsa" 2>&1`
+        else
+	        ALSA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "alsa" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$ALSA_PKG_ERRORS" >&5
+
+	HAVE_ALSA=0
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	HAVE_ALSA=0
+else
+	ALSA_CFLAGS=$pkg_cv_ALSA_CFLAGS
+	ALSA_LIBS=$pkg_cv_ALSA_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	HAVE_ALSA=1
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBSAMPLERATE" >&5
+$as_echo_n "checking for LIBSAMPLERATE... " >&6; }
+
+if test -n "$LIBSAMPLERATE_CFLAGS"; then
+    pkg_cv_LIBSAMPLERATE_CFLAGS="$LIBSAMPLERATE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"samplerate\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "samplerate") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBSAMPLERATE_CFLAGS=`$PKG_CONFIG --cflags "samplerate" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBSAMPLERATE_LIBS"; then
+    pkg_cv_LIBSAMPLERATE_LIBS="$LIBSAMPLERATE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"samplerate\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "samplerate") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBSAMPLERATE_LIBS=`$PKG_CONFIG --libs "samplerate" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LIBSAMPLERATE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "samplerate" 2>&1`
+        else
+	        LIBSAMPLERATE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "samplerate" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LIBSAMPLERATE_PKG_ERRORS" >&5
+
+	HAVE_LIBSAMPLERATE=0
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	HAVE_LIBSAMPLERATE=0
+else
+	LIBSAMPLERATE_CFLAGS=$pkg_cv_LIBSAMPLERATE_CFLAGS
+	LIBSAMPLERATE_LIBS=$pkg_cv_LIBSAMPLERATE_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	HAVE_LIBSAMPLERATE=1
+fi
     if test x"$HAVE_LIBSAMPLERATE" = "x1"; then
         $as_echo "#define HAVE_LIBSAMPLERATE 1" >>confdefs.h
 
         if test x"$static_libsamplerate" = "xyes"; then
             _libsamplerate_libdir=`$PKG_CONFIG --errors-to-stdout --variable=libdir samplerate`
             LIBSAMPLERATE_LIBS="$_libsamplerate_libdir""/libsamplerate.a"
+            LIBSAMPLERATE_LIBS="$LIBSAMPLERATE_LIBS -lm"
         fi
-        LIBSAMPLERATE_LIBS="$LIBSAMPLERATE_LIBS -lm"
     fi
 fi
 
@@ -6677,7 +7521,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -6723,7 +7567,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -6747,7 +7591,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -6792,7 +7636,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -6816,7 +7660,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -6848,6 +7692,8 @@ _ACEOF
 esac
 rm -rf conftest*
   fi
+
+
 fi
 
 
@@ -6999,99 +7845,34 @@ if test "${with_debug_smartcard+set}" = set; then :
 fi
 
 
-#
-# target-specific stuff
-#
-# strip leading colon from rpath
-rpath=`echo $rpath |sed 's/^://'`
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
-  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
-  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+# Check whether --with-debug-credssp was given.
+if test "${with_debug_credssp+set}" = set; then :
+  withval=$with_debug_credssp;
+	if test $withval != "no";
+	then
+		if test x"$WITH_CREDSSP" = "x1"; then
+		   $as_echo "#define WITH_DEBUG_CREDSSP 1" >>confdefs.h
 
+		fi
+	fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$host_alias" = x; then
-  ac_cv_host=$ac_cv_build
-else
-  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
 fi
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
 
+#
+# target-specific stuff
+#
 case "$host" in
-*-*-solaris*)
-    LDFLAGS="$LDFLAGS -R$rpath"
-    ;;
-*-dec-osf*)
-    LDFLAGS="$LDFLAGS -Wl,-rpath,$rpath"
-    ;;
 *-*-hpux*)
     CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED"
     ;;
 *-*-irix6.5*)
-    LIBS="$LIBS -L$ssldir/lib32 -lcrypto"
+    LIBS="-L$ssldir/lib32 $LIBS"
     CFLAGS="$CFLAGS -D__SGI_IRIX__"
     ;;
 esac
 
-
 ac_config_files="$ac_config_files Makefile"
 
 cat >confcache <<\_ACEOF
@@ -7538,16 +8319,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -7607,28 +8388,16 @@ else
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-	test -d "$1/.";
-      else
-	case $1 in #(
-	-*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -7649,8 +8418,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by rdesktop $as_me 1.7.0, which was
-generated by GNU Autoconf 2.68.  Invocation command line was
+This file was extended by rdesktop $as_me 1.8.3, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -7702,11 +8471,11 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-rdesktop config.status 1.7.0
-configured by $0, generated by GNU Autoconf 2.68,
+rdesktop config.status 1.8.3
+configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -7784,7 +8553,7 @@ fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
   \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
diff --git a/src/VBox/RDP/client/configure.ac b/src/VBox/RDP/client-1.8.3/configure.ac
similarity index 88%
rename from src/VBox/RDP/client/configure.ac
rename to src/VBox/RDP/client-1.8.3/configure.ac
index 2f7249a..9f99c94 100644
--- a/src/VBox/RDP/client/configure.ac
+++ b/src/VBox/RDP/client-1.8.3/configure.ac
@@ -1,7 +1,9 @@
-AC_INIT(rdesktop, 1.7.0)
+AC_INIT(rdesktop, 1.8.3)
 
 AC_CONFIG_SRCDIR([rdesktop.c])
 
+AC_CANONICAL_HOST
+
 AC_PROG_CC
 if test "$GCC" = yes; then
     CFLAGS="$CFLAGS -Wall"
@@ -25,8 +27,8 @@ if test "$no_x" = "yes"; then
     echo
     exit 1
 fi
-
-AC_PATH_PROG(PKG_CONFIG, pkg-config)
+    
+AC_PATH_TOOL(PKG_CONFIG, pkg-config)
 
 AC_SEARCH_LIBS(socket, socket)
 AC_SEARCH_LIBS(inet_aton, resolv)
@@ -51,8 +53,6 @@ m4_ifdef([PKG_CHECK_MODULES], [], [
 		])
 ])
 
-rpath=""
-
 #
 # OpenSSL detection borrowed from stunnel
 #
@@ -98,15 +98,60 @@ AC_DEFINE_UNQUOTED(ssldir, "$ssldir")
 
 dnl Add OpenSSL includes and libraries
 CFLAGS="$CFLAGS -I$ssldir/include"
-AC_ARG_ENABLE(static-openssl,
+AC_ARG_ENABLE(static-openssl, 
              [  --enable-static-openssl link OpenSSL statically],
-             [
-LIBS="$LIBS $ssldir/lib/libcrypto.a"
-             ],
-             [
-LIBS="$LIBS -L$ssldir/lib -lcrypto"
-rpath="$rpath:$ssldir/lib"
-             ])
+             [static_openssl=yes], 
+             [static_openssl=no])
+if test x"$static_openssl" = "xyes"; then
+    # OpenSSL generally relies on libz
+    AC_SEARCH_LIBS(deflate, z)
+    LIBS="-L$ssldir/lib -L$ssldir/lib64 -Wl,-Bstatic -lssl -lcrypto -Wl,-Bdynamic $LIBS"
+else
+    LIBS="-L$ssldir/lib -L$ssldir/lib64 -lssl -lcrypto $LIBS"
+
+    #
+    # target-specific stuff
+    #
+    case "$host" in
+    *-*-solaris*)
+        LDFLAGS="$LDFLAGS -R$ssldir/lib"
+        ;;
+    *-dec-osf*)
+        LDFLAGS="$LDFLAGS -Wl,-rpath,$ssldir/lib"
+        ;;
+    esac
+fi
+
+dnl CredSSP feature
+AC_ARG_ENABLE([credssp], AS_HELP_STRING([--disable-credssp], [disable support for CredSSP]))
+AC_ARG_ENABLE([static-gssglue], AS_HELP_STRING([--enable-static-gssglue]), 
+	      [static_gssglue=yes], [static_gssglue=no])
+AS_IF([test "x$enable_credssp" != "xno"], [
+	  if test -n "$PKG_CONFIG"; then
+	    PKG_CHECK_MODULES(GSSGLUE, libgssglue, [WITH_CREDSSP=1], [WITH_CREDSSP=0])
+	  fi
+
+	  if test x"$WITH_CREDSSP" = "x1"; then
+	      CREDSSPOBJ="cssp.o"
+	      CFLAGS="$CFLAGS $GSSGLUE_CFLAGS"
+
+	      AS_IF([test "x$static_gssglue" != "xno"], [
+	          LIBS="$LIBS -Wl,-Bstatic -lgssglue -Wl,-Bdynamic"
+	      ], [
+	          LIBS="$LIBS -lgssglue"
+	      ])
+
+	      AC_DEFINE(WITH_CREDSSP)
+	  else
+		echo
+		echo "CredSSP support requires libgssglue, install the dependency"
+		echo "or disable the feature using --disable-credssp."
+		echo
+		exit 1
+	  fi
+])
+AC_SUBST(CREDSSPOBJ)
+
 # xrandr
 if test -n "$PKG_CONFIG"; then
     PKG_CHECK_MODULES(XRANDR, xrandr, [HAVE_XRANDR=1], [HAVE_XRANDR=0])
@@ -117,46 +162,49 @@ if test x"$HAVE_XRANDR" = "x1"; then
     AC_DEFINE(HAVE_XRANDR)
 fi
 
-AC_ARG_ENABLE(smartcard,
-             [  --enable-smartcard	  Enables smart-card support.
-	     ],
-             [
-	     	case "$OSTYPE" in
-			darwin*)
-				AC_CHECK_HEADER(PCSC/pcsclite.h, [WITH_SCARD=1], [WITH_SCARD=0])
-				PCSCLITE_CFLAGS=""
-				PCSCLITE_LIBS="-framework PCSC"
-				;;
-			*)
-				if test -n "$PKG_CONFIG"; then
-					PKG_CHECK_MODULES(PCSCLITE, libpcsclite, [WITH_SCARD=1], [WITH_SCARD=0])
-				fi
-				;;
-		esac
-
-		if test x"$WITH_SCARD" = "x1"; then
-			SCARDOBJ="scard.o"
-			CFLAGS="$CFLAGS $PCSCLITE_CFLAGS"
-			LIBS="$LIBS $PCSCLITE_LIBS"
-			AC_DEFINE(WITH_SCARD)
+dnl Smartcard support
+AC_ARG_ENABLE(smartcard, AS_HELP_STRING([--disable-smartcard], [disable support for smartcard]))
+AS_IF([test "x$enable_smartcard" != "xno"], [
+	case "$OSTYPE" in
+	     darwin*)
+		AC_CHECK_HEADER(PCSC/pcsclite.h, [WITH_SCARD=1], [WITH_SCARD=0])
+		PCSCLITE_CFLAGS=""
+		PCSCLITE_LIBS="-framework PCSC"
+		;;
+	     *)
+		if test -n "$PKG_CONFIG"; then
+		   PKG_CHECK_MODULES(PCSCLITE, libpcsclite, [WITH_SCARD=1], [WITH_SCARD=0])
 		fi
+		;;
+	esac
+
+	if test x"$WITH_SCARD" = "x1"; then
+	   SCARDOBJ="scard.o"
+	   CFLAGS="$CFLAGS $PCSCLITE_CFLAGS"
+	   LIBS="$LIBS $PCSCLITE_LIBS"
+	   AC_DEFINE(WITH_SCARD)
+	else
+	   echo
+	   echo "SmartCard support requires PCSC, install the dependency"
+	   echo "or disable the feature using --disable-smartcard."
+	   echo
+	   exit 1
+	fi
 
-		AC_MSG_CHECKING([for old version of PCSC])
-		AC_TRY_LINK([
-			#include <stdlib.h>
-			#ifdef __APPLE__
-			#include <PCSC/wintypes.h>
-			#include <PCSC/winscard.h>
-			#else
-			#include <winscard.h>
-			#endif
-			],
-			[SCardControl(NULL, NULL, 0, NULL, NULL);],
-			[AC_MSG_RESULT(yes) AC_DEFINE(WITH_PCSC120, 1, [old version of PCSC])],
-			[AC_MSG_RESULT(no)]
-		)
-             ])
-
+	AC_MSG_CHECKING([for old version of PCSC])
+	AC_TRY_LINK([
+		#include <stdlib.h>
+		#ifdef __APPLE__
+		#include <PCSC/wintypes.h>
+		#include <PCSC/winscard.h>
+		#else
+		#include <winscard.h>
+		#endif
+		],
+		[SCardControl(NULL, NULL, 0, NULL, NULL);],
+		[AC_MSG_RESULT(yes) AC_DEFINE(WITH_PCSC120, 1, [old version of PCSC])],
+		[AC_MSG_RESULT(no)])
+])
 AC_SUBST(SCARDOBJ)
 
 #
@@ -257,8 +305,8 @@ if test -n "$PKG_CONFIG"; then
         if test x"$static_libsamplerate" = "xyes"; then
             _libsamplerate_libdir=`$PKG_CONFIG --errors-to-stdout --variable=libdir samplerate`
             LIBSAMPLERATE_LIBS="$_libsamplerate_libdir""/libsamplerate.a"
+            LIBSAMPLERATE_LIBS="$LIBSAMPLERATE_LIBS -lm"
         fi
-        LIBSAMPLERATE_LIBS="$LIBSAMPLERATE_LIBS -lm"
     fi
 fi
 
@@ -903,29 +951,30 @@ AC_ARG_WITH(debug-smartcard,
 	fi
     ])
 
+AC_ARG_WITH(debug-credssp,
+    [  --with-debug-credssp	enable debugging of CredSSP code],
+    [
+	if test $withval != "no";
+	then
+		if test x"$WITH_CREDSSP" = "x1"; then
+		   AC_DEFINE(WITH_DEBUG_CREDSSP,1)
+		fi
+	fi
+    ])
+
 #
 # target-specific stuff
 #
-# strip leading colon from rpath
-rpath=`echo $rpath |sed 's/^://'`
-AC_CANONICAL_HOST
 case "$host" in
-*-*-solaris*)
-    LDFLAGS="$LDFLAGS -R$rpath"
-    ;;
-*-dec-osf*)
-    LDFLAGS="$LDFLAGS -Wl,-rpath,$rpath"
-    ;;
 *-*-hpux*)
     CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED"
     ;;
 *-*-irix6.5*)
-    LIBS="$LIBS -L$ssldir/lib32 -lcrypto"
+    LIBS="-L$ssldir/lib32 $LIBS"
     CFLAGS="$CFLAGS -D__SGI_IRIX__"
     ;;
 esac
 
-
 AC_OUTPUT(Makefile)
 
 dnl Local Variables:
diff --git a/src/VBox/RDP/client/constants.h b/src/VBox/RDP/client-1.8.3/constants.h
similarity index 79%
rename from src/VBox/RDP/client/constants.h
rename to src/VBox/RDP/client-1.8.3/constants.h
index ee49c95..46e4772 100644
--- a/src/VBox/RDP/client/constants.h
+++ b/src/VBox/RDP/client-1.8.3/constants.h
@@ -42,6 +42,31 @@ enum ISO_PDU_CODE
 	ISO_PDU_ER = 0x70	/* Error */
 };
 
+/* RDP protocol negotiating constants */
+enum RDP_NEG_TYPE_CODE
+{
+	RDP_NEG_REQ = 1,
+	RDP_NEG_RSP = 2,
+	RDP_NEG_FAILURE = 3
+};
+
+enum RDP_NEG_REQ_CODE
+{
+	PROTOCOL_RDP = 0,
+	PROTOCOL_SSL = 1,
+	PROTOCOL_HYBRID = 2
+};
+
+enum RDP_NEG_FAILURE_CODE
+{
+	SSL_REQUIRED_BY_SERVER = 1,
+	SSL_NOT_ALLOWED_BY_SERVER = 2,
+	SSL_CERT_NOT_ON_SERVER = 3,
+	INCONSISTENT_FLAGS = 4,
+	HYBRID_REQUIRED_BY_SERVER = 5,
+	SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 6
+};
+
 /* MCS PDU codes */
 enum MCS_PDU_TYPE
 {
@@ -62,6 +87,10 @@ enum MCS_PDU_TYPE
 #define BER_TAG_INTEGER		2
 #define BER_TAG_OCTET_STRING	4
 #define BER_TAG_RESULT		10
+#define BER_TAG_SEQUENCE	16
+#define BER_TAG_CONSTRUCTED	0x20
+#define BER_TAG_CTXT_SPECIFIC	0x80
+
 #define MCS_TAG_DOMAIN_PARAMS	0x30
 
 #define MCS_GLOBAL_CHANNEL	1003
@@ -87,38 +116,50 @@ enum MCS_PDU_TYPE
 #define SEC_TAG_CLI_INFO	0xc001
 #define SEC_TAG_CLI_CRYPT	0xc002
 #define SEC_TAG_CLI_CHANNELS    0xc003
-#define SEC_TAG_CLI_4           0xc004
+#define SEC_TAG_CLI_CLUSTER     0xc004
 
 #define SEC_TAG_PUBKEY		0x0006
 #define SEC_TAG_KEYSIG		0x0008
 
 #define SEC_RSA_MAGIC		0x31415352	/* RSA1 */
 
+/* Client cluster constants */
+#define SEC_CC_REDIRECTION_SUPPORTED          0x00000001
+#define SEC_CC_REDIRECT_SESSIONID_FIELD_VALID 0x00000002
+#define SEC_CC_REDIRECTED_SMARTCARD           0x00000040
+#define SEC_CC_REDIRECT_VERSION_MASK          0x0000003c
+
+#define SEC_CC_REDIRECT_VERSION_3             0x02
+#define SEC_CC_REDIRECT_VERSION_4             0x03
+#define SEC_CC_REDIRECT_VERSION_5             0x04
+#define SEC_CC_REDIRECT_VERSION_6             0x05
+
 /* RDP licensing constants */
 #define LICENCE_TOKEN_SIZE	10
 #define LICENCE_HWID_SIZE	20
 #define LICENCE_SIGNATURE_SIZE	16
 
-#define LICENCE_TAG_DEMAND	0x01
-#define LICENCE_TAG_AUTHREQ	0x02
-#define LICENCE_TAG_ISSUE	0x03
-#define LICENCE_TAG_REISSUE	0x04
-#define LICENCE_TAG_PRESENT	0x12
-#define LICENCE_TAG_REQUEST	0x13
-#define LICENCE_TAG_AUTHRESP	0x15
-#define LICENCE_TAG_RESULT	0xff
+#define LICENCE_TAG_REQUEST                     0x01
+#define LICENCE_TAG_PLATFORM_CHALLANGE          0x02
+#define LICENCE_TAG_NEW_LICENCE                 0x03
+#define LICENCE_TAG_UPGRADE_LICENCE             0x04
+#define LICENCE_TAG_LICENCE_INFO                0x12
+#define LICENCE_TAG_NEW_LICENCE_REQUEST         0x13
+#define LICENCE_TAG_PLATFORM_CHALLANGE_RESPONSE 0x15
+#define LICENCE_TAG_ERROR_ALERT                 0xff
 
-#define LICENCE_TAG_USER	0x000f
-#define LICENCE_TAG_HOST	0x0010
+#define BB_CLIENT_USER_NAME_BLOB	0x000f
+#define BB_CLIENT_MACHINE_NAME_BLOB	0x0010
 
 /* RDP PDU codes */
 enum RDP_PDU_TYPE
 {
 	RDP_PDU_DEMAND_ACTIVE = 1,
 	RDP_PDU_CONFIRM_ACTIVE = 3,
-	RDP_PDU_REDIRECT = 4,	/* MS Server 2003 Session Redirect */
+	RDP_PDU_REDIRECT = 4,	/* Standard Server Redirect */
 	RDP_PDU_DEACTIVATE = 6,
-	RDP_PDU_DATA = 7
+	RDP_PDU_DATA = 7,
+	RDP_PDU_ENHANCED_REDIRECT = 10	/* Enhanced Server Redirect */
 };
 
 enum RDP_DATA_PDU_TYPE
@@ -133,7 +174,8 @@ enum RDP_DATA_PDU_TYPE
 	RDP_DATA_PDU_LOGON = 38,	/* PDUTYPE2_SAVE_SESSION_INFO */
 	RDP_DATA_PDU_FONT2 = 39,
 	RDP_DATA_PDU_KEYBOARD_INDICATORS = 41,
-	RDP_DATA_PDU_DISCONNECT = 47
+	RDP_DATA_PDU_DISCONNECT = 47,
+	RDP_DATA_PDU_AUTORECONNECT_STATUS = 50
 };
 
 enum RDP_SAVE_SESSION_PDU_TYPE
@@ -286,12 +328,16 @@ enum RDP_INPUT_DEVICE
 #define RDP_SOURCE		"MSTSC"
 
 /* Logon flags */
-#define RDP_LOGON_AUTO		0x0008
-#define RDP_LOGON_NORMAL	0x0033
-#define RDP_LOGON_COMPRESSION	0x0080	/* mppc compression with 8kB histroy buffer */
-#define RDP_LOGON_BLOB		0x0100
-#define RDP_LOGON_COMPRESSION2	0x0200	/* rdp5 mppc compression with 64kB history buffer */
-#define RDP_LOGON_LEAVE_AUDIO	0x2000
+#define RDP_INFO_MOUSE                0x00000001
+#define RDP_INFO_DISABLECTRLALTDEL    0x00000002
+#define RDP_INFO_AUTOLOGON 	      0x00000008
+#define RDP_INFO_UNICODE              0x00000010
+#define RDP_INFO_MAXIMIZESHELL        0x00000020
+#define RDP_INFO_COMPRESSION	      0x00000080	/* mppc compression with 8kB histroy buffer */
+#define RDP_INFO_ENABLEWINDOWSKEY     0x00000100
+#define RDP_INFO_COMPRESSION2	      0x00000200	/* rdp5 mppc compression with 64kB history buffer */
+#define RDP_INFO_REMOTE_CONSOLE_AUDIO 0x00002000
+#define RDP_INFO_PASSWORD_IS_SC_PIN   0x00040000
 
 #define RDP5_DISABLE_NOTHING	0x00
 #define RDP5_NO_WALLPAPER	0x01
@@ -409,8 +455,29 @@ enum RDP_INPUT_DEVICE
 #define RD_STATUS_CANCELLED                0xc0000120
 #define RD_STATUS_DIRECTORY_NOT_EMPTY      0xc0000101
 
+/* RDPSND constants */
+#define TSSNDCAPS_ALIVE                    0x00000001
+#define TSSNDCAPS_VOLUME                   0x00000002
 
 /* RDPDR constants */
+
+#define RDPDR_CTYP_CORE                 0x4472
+#define RDPDR_CTYP_PRN                  0x5052
+
+#define PAKID_CORE_SERVER_ANNOUNCE      0x496e
+#define PAKID_CORE_CLIENTID_CONFIRM     0x4343
+#define PAKID_CORE_CLIENT_NAME          0x434e
+#define PAKID_CORE_DEVICE_LIST_ANNOUNCE 0x4441
+#define PAKID_CORE_DEVICE_REPLY         0x6472
+#define PAKID_CORE_DEVICE_IOREQUEST     0x4952
+#define PAKID_CORE_DEVICE_IOCOMPLETION  0x4943
+#define PAKID_CORE_SERVER_CAPABILITY    0x5350
+#define PAKID_CORE_CLIENT_CAPABILITY    0x4350
+#define PAKID_CORE_DEVICELIST_REMOVE    0x444d
+#define PAKID_PRN_CACHE_DATA            0x5043
+#define PAKID_CORE_USER_LOGGEDON        0x554c
+#define PAKID_PRN_USING_XPS             0x5543
+
 #define RDPDR_MAX_DEVICES               0x10
 #define DEVICE_TYPE_SERIAL              0x01
 #define DEVICE_TYPE_PARALLEL            0x02
@@ -434,7 +501,10 @@ enum RDP_INPUT_DEVICE
 #define exDiscReasonOutOfMemory				0x0006
 #define exDiscReasonServerDeniedConnection		0x0007
 #define exDiscReasonServerDeniedConnectionFips		0x0008
-#define exDiscReasonWindows7Disconnect                  0x000b	/* unofficial */
+#define exDiscReasonServerInsufficientPrivileges        0x0009
+#define exDiscReasonServerFreshCredentialsRequired      0x000a
+#define exDiscReasonRPCInitiatedDisconnectByUser        0x000b
+#define exDiscReasonByUser                              0x000c
 #define exDiscReasonLicenseInternal			0x0100
 #define exDiscReasonLicenseNoLicenseServer		0x0101
 #define exDiscReasonLicenseNoLicense			0x0102
@@ -472,7 +542,7 @@ enum RDP_INPUT_DEVICE
 enum RDP_PDU_REDIRECT_FLAGS
 {
 	PDU_REDIRECT_HAS_IP = 0x1,
-	PDU_REDIRECT_HAS_COOKIE = 0x2,
+	PDU_REDIRECT_HAS_LOAD_BALANCE_INFO = 0x2,
 	PDU_REDIRECT_HAS_USERNAME = 0x4,
 	PDU_REDIRECT_HAS_DOMAIN = 0x8,
 	PDU_REDIRECT_HAS_PASSWORD = 0x10,
diff --git a/src/VBox/RDP/client-1.8.3/cssp.c b/src/VBox/RDP/client-1.8.3/cssp.c
new file mode 100644
index 0000000..b4c3417
--- /dev/null
+++ b/src/VBox/RDP/client-1.8.3/cssp.c
@@ -0,0 +1,918 @@
+/* -*- c-basic-offset: 8 -*-
+   rdesktop: A Remote Desktop Protocol client.
+   CredSSP layer and kerberos support.
+   Copyright 2012-2013 Henrik Andersson <hean01 at cendio.se> for Cendio AB
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the General Public License version 2 (GPLv2) at this time for any software where
+ * a choice of GPL license versions is made available with the language indicating
+ * that GPLv2 or any later version may be used, or where a choice of which version
+ * of the GPL is applied is otherwise unspecified.
+ */
+
+#include <gssapi/gssapi.h>
+#include "rdesktop.h"
+
+extern RD_BOOL g_use_password_as_pin;
+
+extern char *g_sc_csp_name;
+extern char *g_sc_reader_name;
+extern char *g_sc_card_name;
+extern char *g_sc_container_name;
+
+static gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc =
+	{ 9, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
+
+
+static void
+s_realloc(STREAM s, unsigned int size)
+{
+	unsigned char *data;
+
+	if (s->size >= size)
+		return;
+
+	data = s->data;
+	s->size = size;
+	s->data = xrealloc(data, size);
+	s->p = s->data + (s->p - data);
+	s->end = s->data + (s->end - data);
+	s->iso_hdr = s->data + (s->iso_hdr - data);
+	s->mcs_hdr = s->data + (s->mcs_hdr - data);
+	s->sec_hdr = s->data + (s->sec_hdr - data);
+	s->rdp_hdr = s->data + (s->rdp_hdr - data);
+	s->channel_hdr = s->data + (s->channel_hdr - data);
+}
+
+static void
+s_free(STREAM s)
+{
+	free(s->data);
+	free(s);
+}
+
+static STREAM
+ber_wrap_hdr_data(int tagval, STREAM in)
+{
+	STREAM out;
+	int size = s_length(in) + 16;
+
+	out = xmalloc(sizeof(struct stream));
+	memset(out, 0, sizeof(struct stream));
+	out->data = xmalloc(size);
+	out->size = size;
+	out->p = out->data;
+
+	ber_out_header(out, tagval, s_length(in));
+	out_uint8p(out, in->data, s_length(in));
+	s_mark_end(out);
+
+	return out;
+}
+
+
+static void
+cssp_gss_report_error(OM_uint32 code, char *str, OM_uint32 major_status, OM_uint32 minor_status)
+{
+	OM_uint32 msgctx = 0, ms;
+	gss_buffer_desc status_string;
+
+	error("GSS error [%d:%d:%d]: %s\n", (major_status & 0xff000000) >> 24,	// Calling error
+	      (major_status & 0xff0000) >> 16,	// Routine error
+	      major_status & 0xffff,	// Supplementary info bits
+	      str);
+
+	do
+	{
+		ms = gss_display_status(&minor_status, major_status,
+					code, GSS_C_NULL_OID, &msgctx, &status_string);
+		if (ms != GSS_S_COMPLETE)
+			continue;
+
+		error(" - %s\n", status_string.value);
+
+	}
+	while (ms == GSS_S_COMPLETE && msgctx);
+
+}
+
+
+static RD_BOOL
+cssp_gss_mech_available(gss_OID mech)
+{
+	int mech_found;
+	OM_uint32 major_status, minor_status;
+	gss_OID_set mech_set;
+
+	mech_found = 0;
+
+	if (mech == GSS_C_NO_OID)
+		return True;
+
+	major_status = gss_indicate_mechs(&minor_status, &mech_set);
+	if (!mech_set)
+		return False;
+
+	if (GSS_ERROR(major_status))
+	{
+		cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to get available mechs on system",
+				      major_status, minor_status);
+		return False;
+	}
+
+	gss_test_oid_set_member(&minor_status, mech, mech_set, &mech_found);
+
+	if (GSS_ERROR(major_status))
+	{
+		cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to match mechanism in set",
+				      major_status, minor_status);
+		return False;
+	}
+
+	if (!mech_found)
+		return False;
+
+	return True;
+}
+
+static RD_BOOL
+cssp_gss_get_service_name(char *server, gss_name_t * name)
+{
+	gss_buffer_desc output;
+	OM_uint32 major_status, minor_status;
+
+	const char service_name[] = "TERMSRV";
+
+	gss_OID type = (gss_OID) GSS_C_NT_HOSTBASED_SERVICE;
+	int size = (strlen(service_name) + 1 + strlen(server) + 1);
+
+	output.value = malloc(size);
+	snprintf(output.value, size, "%s@%s", service_name, server);
+	output.length = strlen(output.value) + 1;
+
+	major_status = gss_import_name(&minor_status, &output, type, name);
+
+	if (GSS_ERROR(major_status))
+	{
+		cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to create service principal name",
+				      major_status, minor_status);
+		return False;
+	}
+
+	gss_release_buffer(&minor_status, &output);
+
+	return True;
+
+}
+
+static RD_BOOL
+cssp_gss_wrap(gss_ctx_id_t * ctx, STREAM in, STREAM out)
+{
+	int conf_state;
+	OM_uint32 major_status;
+	OM_uint32 minor_status;
+	gss_buffer_desc inbuf, outbuf;
+
+	inbuf.value = in->data;
+	inbuf.length = s_length(in);
+
+	major_status = gss_wrap(&minor_status, ctx, True,
+				GSS_C_QOP_DEFAULT, &inbuf, &conf_state, &outbuf);
+
+	if (major_status != GSS_S_COMPLETE)
+	{
+		cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to encrypt and sign message",
+				      major_status, minor_status);
+		return False;
+	}
+
+	if (!conf_state)
+	{
+		error("GSS Confidentiality failed, no encryption of message performed.");
+		return False;
+	}
+
+	// write enc data to out stream
+	out->data = out->p = xmalloc(outbuf.length);
+	out->size = outbuf.length;
+	out_uint8p(out, outbuf.value, outbuf.length);
+	s_mark_end(out);
+
+	gss_release_buffer(&minor_status, &outbuf);
+
+	return True;
+}
+
+static RD_BOOL
+cssp_gss_unwrap(gss_ctx_id_t * ctx, STREAM in, STREAM out)
+{
+	OM_uint32 major_status;
+	OM_uint32 minor_status;
+	gss_qop_t qop_state;
+	gss_buffer_desc inbuf, outbuf;
+	int conf_state;
+
+	inbuf.value = in->data;
+	inbuf.length = s_length(in);
+
+	major_status = gss_unwrap(&minor_status, ctx, &inbuf, &outbuf, &conf_state, &qop_state);
+
+	if (major_status != GSS_S_COMPLETE)
+	{
+		cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to decrypt message",
+				      major_status, minor_status);
+		return False;
+	}
+
+	out->data = out->p = xmalloc(outbuf.length);
+	out->size = outbuf.length;
+	out_uint8p(out, outbuf.value, outbuf.length);
+	s_mark_end(out);
+
+	gss_release_buffer(&minor_status, &outbuf);
+
+	return True;
+}
+
+#ifdef WITH_DEBUG_CREDSSP
+void
+streamsave(STREAM s, char *fn)
+{
+	FILE *f = fopen(fn, "wb");
+	fwrite(s->data, s_length(s), 1, f);
+	fclose(f);
+}
+#endif
+
+static STREAM
+cssp_encode_tspasswordcreds(char *username, char *password, char *domain)
+{
+	STREAM out, h1, h2;
+	struct stream tmp = { 0 };
+	struct stream message = { 0 };
+
+	memset(&tmp, 0, sizeof(tmp));
+	memset(&message, 0, sizeof(message));
+
+	// domainName [0]
+	s_realloc(&tmp, 4 + strlen(domain) * sizeof(uint16));
+	s_reset(&tmp);
+	rdp_out_unistr(&tmp, domain, strlen(domain) * sizeof(uint16));
+	s_mark_end(&tmp);
+	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// userName [1]
+	s_realloc(&tmp, 4 + strlen(username) * sizeof(uint16));
+	s_reset(&tmp);
+	rdp_out_unistr(&tmp, username, strlen(username) * sizeof(uint16));
+	s_mark_end(&tmp);
+
+	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// password [2]
+	s_realloc(&tmp, 4 + strlen(password) * sizeof(uint16));
+	s_reset(&tmp);
+	rdp_out_unistr(&tmp, password, strlen(password) * sizeof(uint16));
+	s_mark_end(&tmp);
+	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// build message
+	out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
+
+	// cleanup
+	xfree(tmp.data);
+	xfree(message.data);
+	return out;
+}
+
+/* KeySpecs from wincrypt.h */
+#define AT_KEYEXCHANGE 1
+#define AT_SIGNATURE   2
+
+static STREAM
+cssp_encode_tscspdatadetail(unsigned char keyspec, char *card, char *reader, char *container,
+			    char *csp)
+{
+	STREAM out;
+	STREAM h1, h2;
+	struct stream tmp = { 0 };
+	struct stream message = { 0 };
+
+	// keySpec [0]
+	s_realloc(&tmp, sizeof(uint8));
+	s_reset(&tmp);
+	out_uint8(&tmp, keyspec);
+	s_mark_end(&tmp);
+	h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// cardName [1]
+	if (card)
+	{
+		s_realloc(&tmp, 4 + strlen(card) * sizeof(uint16));
+		s_reset(&tmp);
+		rdp_out_unistr(&tmp, card, strlen(card) * sizeof(uint16));
+		s_mark_end(&tmp);
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h2);
+		s_free(h1);
+	}
+
+	// readerName [2]
+	if (reader)
+	{
+		s_realloc(&tmp, 4 + strlen(reader) * sizeof(uint16));
+		s_reset(&tmp);
+		rdp_out_unistr(&tmp, reader, strlen(reader) * sizeof(uint16));
+		s_mark_end(&tmp);
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h2);
+		s_free(h1);
+	}
+
+	// containerName [3]
+	if (container)
+	{
+		s_realloc(&tmp, 4 + strlen(container) * sizeof(uint16));
+		s_reset(&tmp);
+		rdp_out_unistr(&tmp, container, strlen(container) * sizeof(uint16));
+		s_mark_end(&tmp);
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h2);
+		s_free(h1);
+	}
+
+	// cspName [4]
+	if (csp)
+	{
+		s_realloc(&tmp, 4 + strlen(csp) * sizeof(uint16));
+		s_reset(&tmp);
+		rdp_out_unistr(&tmp, csp, strlen(csp) * sizeof(uint16));
+		s_mark_end(&tmp);
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 4, h2);
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h2);
+		s_free(h1);
+	}
+
+	s_mark_end(&message);
+
+	// build message
+	out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
+
+	// cleanup
+	free(tmp.data);
+	free(message.data);
+	return out;
+}
+
+static STREAM
+cssp_encode_tssmartcardcreds(char *username, char *password, char *domain)
+{
+	STREAM out, h1, h2;
+	struct stream tmp = { 0 };
+	struct stream message = { 0 };
+
+	// pin [0]
+	s_realloc(&tmp, strlen(password) * sizeof(uint16));
+	s_reset(&tmp);
+	rdp_out_unistr(&tmp, password, strlen(password) * sizeof(uint16));
+	s_mark_end(&tmp);
+	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// cspData[1]        
+	h2 = cssp_encode_tscspdatadetail(AT_KEYEXCHANGE, g_sc_card_name, g_sc_reader_name,
+					 g_sc_container_name, g_sc_csp_name);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// userHint [2]
+	if (username && strlen(username))
+	{
+		s_realloc(&tmp, strlen(username) * sizeof(uint16));
+		s_reset(&tmp);
+		rdp_out_unistr(&tmp, username, strlen(username) * sizeof(uint16));
+		s_mark_end(&tmp);
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h2);
+		s_free(h1);
+	}
+
+	// domainHint [3]
+	if (domain && strlen(domain))
+	{
+		s_realloc(&tmp, strlen(domain) * sizeof(uint16));
+		s_reset(&tmp);
+		rdp_out_unistr(&tmp, domain, strlen(domain) * sizeof(uint16));
+		s_mark_end(&tmp);
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h2);
+		s_free(h1);
+	}
+
+	s_mark_end(&message);
+
+	// build message
+	out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
+
+	// cleanup
+	free(tmp.data);
+	free(message.data);
+	return out;
+}
+
+STREAM
+cssp_encode_tscredentials(char *username, char *password, char *domain)
+{
+	STREAM out;
+	STREAM h1, h2, h3;
+	struct stream tmp = { 0 };
+	struct stream message = { 0 };
+
+	// credType [0]
+	s_realloc(&tmp, sizeof(uint8));
+	s_reset(&tmp);
+	if (g_use_password_as_pin == False)
+	{
+		out_uint8(&tmp, 1);	// TSPasswordCreds
+	}
+	else
+	{
+		out_uint8(&tmp, 2);	// TSSmartCardCreds
+	}
+
+	s_mark_end(&tmp);
+	h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// credentials [1]
+	if (g_use_password_as_pin == False)
+	{
+		h3 = cssp_encode_tspasswordcreds(username, password, domain);
+	}
+	else
+	{
+		h3 = cssp_encode_tssmartcardcreds(username, password, domain);
+	}
+
+	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, h3);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h3);
+	s_free(h2);
+	s_free(h1);
+
+	// Construct ASN.1 message
+	out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
+
+#if WITH_DEBUG_CREDSSP
+	streamsave(out, "tscredentials.raw");
+	printf("Out TSCredentials %ld bytes\n", s_length(out));
+	hexdump(out->data, s_length(out));
+#endif
+
+	// cleanup
+	xfree(message.data);
+	xfree(tmp.data);
+
+	return out;
+}
+
+RD_BOOL
+cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
+{
+	STREAM s;
+	STREAM h1, h2, h3, h4, h5;
+
+	struct stream tmp = { 0 };
+	struct stream message = { 0 };
+
+	memset(&message, 0, sizeof(message));
+	memset(&tmp, 0, sizeof(tmp));
+
+	// version [0]
+	s_realloc(&tmp, sizeof(uint8));
+	s_reset(&tmp);
+	out_uint8(&tmp, 2);
+	s_mark_end(&tmp);
+	h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp);
+	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
+	s_realloc(&message, s_length(&message) + s_length(h1));
+	out_uint8p(&message, h1->data, s_length(h1));
+	s_mark_end(&message);
+	s_free(h2);
+	s_free(h1);
+
+	// negoToken [1]
+	if (token && s_length(token))
+	{
+		h5 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, token);
+		h4 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h5);
+		h3 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, h4);
+		h2 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, h3);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h5);
+		s_free(h4);
+		s_free(h3);
+		s_free(h2);
+		s_free(h1);
+	}
+
+	// authInfo [2]
+	if (auth && s_length(auth))
+	{
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, auth);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
+
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+
+		s_free(h2);
+		s_free(h1);
+	}
+
+	// pubKeyAuth [3]
+	if (pubkey && s_length(pubkey))
+	{
+		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, pubkey);
+		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
+
+		s_realloc(&message, s_length(&message) + s_length(h1));
+		out_uint8p(&message, h1->data, s_length(h1));
+		s_mark_end(&message);
+		s_free(h2);
+		s_free(h1);
+	}
+	s_mark_end(&message);
+
+	// Construct ASN.1 Message
+	// Todo: can h1 be send directly instead of tcp_init() approach
+	h1 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
+	s = tcp_init(s_length(h1));
+	out_uint8p(s, h1->data, s_length(h1));
+	s_mark_end(s);
+	s_free(h1);
+
+#if WITH_DEBUG_CREDSSP
+	streamsave(s, "tsrequest_out.raw");
+	printf("Out TSRequest %ld bytes\n", s_length(s));
+	hexdump(s->data, s_length(s));
+#endif
+
+	tcp_send(s);
+
+	// cleanup
+	xfree(message.data);
+	xfree(tmp.data);
+
+	return True;
+}
+
+
+RD_BOOL
+cssp_read_tsrequest(STREAM token, STREAM pubkey)
+{
+	STREAM s;
+	int length;
+	int tagval;
+
+	s = tcp_recv(NULL, 4);
+
+	if (s == NULL)
+		return False;
+
+	// verify ASN.1 header
+	if (s->p[0] != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
+	{
+		error("Expected BER_TAG_SEQUENCE|BER_TAG_CONSTRUCTED, got %x", s->p[0]);
+		return False;
+	}
+
+	// peek at first 4 bytes to get full message length
+	if (s->p[1] < 0x80)
+		length = s->p[1] - 2;
+	else if (s->p[1] == 0x81)
+		length = s->p[2] - 1;
+	else if (s->p[1] == 0x82)
+		length = (s->p[2] << 8) | s->p[3];
+	else
+		return False;
+
+	// receive the remainings of message
+	s = tcp_recv(s, length);
+
+#if WITH_DEBUG_CREDSSP
+	streamsave(s, "tsrequest_in.raw");
+	printf("In TSRequest token %ld bytes\n", s_length(s));
+	hexdump(s->data, s_length(s));
+#endif
+
+	// parse the response and into nego token
+	if (!ber_in_header(s, &tagval, &length) ||
+	    tagval != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
+		return False;
+
+	// version [0]
+	if (!ber_in_header(s, &tagval, &length) ||
+	    tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0))
+		return False;
+	in_uint8s(s, length);
+
+	// negoToken [1]
+	if (token)
+	{
+		if (!ber_in_header(s, &tagval, &length)
+		    || tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1))
+			return False;
+		if (!ber_in_header(s, &tagval, &length)
+		    || tagval != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
+			return False;
+		if (!ber_in_header(s, &tagval, &length)
+		    || tagval != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
+			return False;
+		if (!ber_in_header(s, &tagval, &length)
+		    || tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0))
+			return False;
+
+		if (!ber_in_header(s, &tagval, &length) || tagval != BER_TAG_OCTET_STRING)
+			return False;
+
+		token->end = token->p = token->data;
+		out_uint8p(token, s->p, length);
+		s_mark_end(token);
+	}
+
+	// pubKey [3]
+	if (pubkey)
+	{
+		if (!ber_in_header(s, &tagval, &length)
+		    || tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3))
+			return False;
+
+		if (!ber_in_header(s, &tagval, &length) || tagval != BER_TAG_OCTET_STRING)
+			return False;
+
+		pubkey->data = pubkey->p = s->p;
+		pubkey->end = pubkey->data + length;
+		pubkey->size = length;
+	}
+
+
+	return True;
+}
+
+RD_BOOL
+cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
+{
+	OM_uint32 actual_time;
+	gss_cred_id_t cred;
+	gss_buffer_desc input_tok, output_tok;
+	gss_name_t target_name;
+	OM_uint32 major_status, minor_status;
+	int context_established = 0;
+	gss_ctx_id_t gss_ctx;
+	gss_OID desired_mech = &_gss_spnego_krb5_mechanism_oid_desc;
+
+	STREAM ts_creds;
+	struct stream token = { 0 };
+	struct stream pubkey = { 0 };
+	struct stream pubkey_cmp = { 0 };
+
+	// Verify that system gss support spnego
+	if (!cssp_gss_mech_available(desired_mech))
+	{
+		warning("CredSSP: System doesn't have support for desired authentication mechanism.\n");
+		return False;
+	}
+
+	// Get service name
+	if (!cssp_gss_get_service_name(server, &target_name))
+	{
+		warning("CredSSP: Failed to get target service name.\n");
+		return False;
+	}
+
+	// Establish tls connection to server
+	if (!tcp_tls_connect())
+	{
+		warning("CredSSP: Failed to establish TLS connection.\n");
+		return False;
+	}
+
+	tcp_tls_get_server_pubkey(&pubkey);
+
+#ifdef WITH_DEBUG_CREDSSP
+	streamsave(&pubkey, "PubKey.raw");
+#endif
+
+	// Enter the spnego loop
+	OM_uint32 actual_services;
+	gss_OID actual_mech;
+	struct stream blob = { 0 };
+
+	gss_ctx = GSS_C_NO_CONTEXT;
+	cred = GSS_C_NO_CREDENTIAL;
+
+	input_tok.length = 0;
+	output_tok.length = 0;
+	minor_status = 0;
+
+	int i = 0;
+
+	do
+	{
+		major_status = gss_init_sec_context(&minor_status,
+						    cred,
+						    &gss_ctx,
+						    target_name,
+						    desired_mech,
+						    GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG,
+						    GSS_C_INDEFINITE,
+						    GSS_C_NO_CHANNEL_BINDINGS,
+						    &input_tok,
+						    &actual_mech,
+						    &output_tok, &actual_services, &actual_time);
+
+		if (GSS_ERROR(major_status))
+		{
+			if (i == 0)
+				error("CredSSP: Initialize failed, do you have correct kerberos tgt initialized ?\n");
+			else
+				error("CredSSP: Negotiation failed.\n");
+
+#ifdef WITH_DEBUG_CREDSSP
+			cssp_gss_report_error(GSS_C_GSS_CODE, "CredSSP: SPNEGO negotiation failed.",
+					      major_status, minor_status);
+#endif
+			goto bail_out;
+		}
+
+		// validate required services
+		if (!(actual_services & GSS_C_CONF_FLAG))
+		{
+			error("CredSSP: Confidiality service required but is not available.\n");
+			goto bail_out;
+		}
+
+		// Send token to server
+		if (output_tok.length != 0)
+		{
+			if (output_tok.length > token.size)
+				s_realloc(&token, output_tok.length);
+			s_reset(&token);
+
+			out_uint8p(&token, output_tok.value, output_tok.length);
+			s_mark_end(&token);
+
+			if (!cssp_send_tsrequest(&token, NULL, NULL))
+				goto bail_out;
+
+			(void) gss_release_buffer(&minor_status, &output_tok);
+		}
+
+		// Read token from server
+		if (major_status & GSS_S_CONTINUE_NEEDED)
+		{
+			(void) gss_release_buffer(&minor_status, &input_tok);
+
+			if (!cssp_read_tsrequest(&token, NULL))
+				goto bail_out;
+
+			input_tok.value = token.data;
+			input_tok.length = s_length(&token);
+		}
+		else
+		{
+			// Send encrypted pubkey for verification to server
+			context_established = 1;
+
+			if (!cssp_gss_wrap(gss_ctx, &pubkey, &blob))
+				goto bail_out;
+
+			if (!cssp_send_tsrequest(NULL, NULL, &blob))
+				goto bail_out;
+
+			context_established = 1;
+		}
+
+		i++;
+
+	}
+	while (!context_established);
+
+	// read tsrequest response and decrypt for public key validation
+	if (!cssp_read_tsrequest(NULL, &blob))
+		goto bail_out;
+
+	if (!cssp_gss_unwrap(gss_ctx, &blob, &pubkey_cmp))
+		goto bail_out;
+
+	pubkey_cmp.data[0] -= 1;
+
+	// validate public key
+	if (memcmp(pubkey.data, pubkey_cmp.data, s_length(&pubkey)) != 0)
+	{
+		error("CredSSP: Cannot guarantee integrity of server connection, MITM ? "
+		      "(public key data mismatch)\n");
+		goto bail_out;
+	}
+
+	// Send TSCredentials
+	ts_creds = cssp_encode_tscredentials(user, password, domain);
+
+	if (!cssp_gss_wrap(gss_ctx, ts_creds, &blob))
+		goto bail_out;
+
+	s_free(ts_creds);
+
+	if (!cssp_send_tsrequest(NULL, &blob, NULL))
+		goto bail_out;
+
+	return True;
+
+      bail_out:
+	xfree(token.data);
+	return False;
+}
diff --git a/src/VBox/RDP/client-1.8.3/ctrl.c b/src/VBox/RDP/client-1.8.3/ctrl.c
new file mode 100644
index 0000000..bb11cf7
--- /dev/null
+++ b/src/VBox/RDP/client-1.8.3/ctrl.c
@@ -0,0 +1,528 @@
+/* -*- c-basic-offset: 8 -*-
+   rdesktop: A Remote Desktop Protocol client.
+   Master/Slave remote controlling
+   Copyright 2013 Henrik Andersson <hean01 at cendio.se> for Cendio AB
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the General Public License version 2 (GPLv2) at this time for any software where
+ * a choice of GPL license versions is made available with the language indicating
+ * that GPLv2 or any later version may be used, or where a choice of which version
+ * of the GPL is applied is otherwise unspecified.
+ */
+
+#include "rdesktop.h"
+#include "ssl.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <limits.h>
+#include <unistd.h>
+
+#define CTRL_LINEBUF_SIZE 1024
+#define CTRL_RESULT_SIZE 32
+#define RDESKTOP_CTRLSOCK_STORE "/.local/share/rdesktop/ctrl"
+
+#define CTRL_HASH_FLAG_SEAMLESS  1
+
+#define ERR_RESULT_OK 0x00
+#define ERR_RESULT_NO_SUCH_COMMAND 0xffffffff
+
+extern RD_BOOL g_seamless_rdp;
+extern uint8 g_static_rdesktop_salt_16[];
+
+static RD_BOOL _ctrl_is_slave;
+static int ctrlsock;
+static char ctrlsock_name[PATH_MAX];
+static struct _ctrl_slave_t *_ctrl_slaves;
+
+#define CMD_SEAMLESS_SPAWN "seamless.spawn"
+
+typedef struct _ctrl_slave_t
+{
+	struct _ctrl_slave_t *prev, *next;
+	int sock;
+	char linebuf[CTRL_LINEBUF_SIZE];
+} _ctrl_slave_t;
+
+
+static void
+_ctrl_slave_new(int sock)
+{
+	_ctrl_slave_t *it, *ns;
+
+	/* initialize new slave list item */
+	ns = (_ctrl_slave_t *) xmalloc(sizeof(_ctrl_slave_t));
+	memset(ns, 0, sizeof(_ctrl_slave_t));
+	ns->sock = sock;
+
+	/* append new slave to end of list */
+	it = _ctrl_slaves;
+
+	/* find last element in list */
+	while (it && it->next)
+		it = it->next;
+
+	/* if last found append new */
+	if (it)
+	{
+		it->next = ns;
+		ns->prev = it;
+	}
+	else
+	{
+		/* no elemnts in list, lets add first */
+		_ctrl_slaves = ns;
+	}
+}
+
+static void
+_ctrl_slave_disconnect(int sock)
+{
+	_ctrl_slave_t *it;
+
+	if (!_ctrl_slaves)
+		return;
+
+	it = _ctrl_slaves;
+
+	/* find slave with sock */
+	while (it->next && it->sock != sock)
+		it = it->next;
+
+	if (it->sock == sock)
+	{
+		/* shutdown socket */
+		shutdown(sock, SHUT_RDWR);
+		close(sock);
+
+		/* remove item from list */
+		if (it == _ctrl_slaves)
+		{
+			if (it->next)
+				_ctrl_slaves = it->next;
+			else
+				_ctrl_slaves = NULL;
+		}
+
+		if (it->prev)
+		{
+			(it->prev)->next = it->next;
+			if (it->next)
+				(it->next)->prev = it->prev;
+		}
+		else if (it->next)
+			(it->next)->prev = NULL;
+
+		xfree(it);
+
+	}
+}
+
+static void
+_ctrl_command_result(_ctrl_slave_t * slave, int result)
+{
+	char buf[64] = { 0 };
+
+	/* translate and send result code back to client */
+	if (result == 0)
+		send(slave->sock, "OK\n", 3, 0);
+	else
+	{
+		snprintf(buf, 64, "ERROR %x\n", result);
+		send(slave->sock, buf, strlen(buf), 0);
+	}
+}
+
+static void
+_ctrl_dispatch_command(_ctrl_slave_t * slave)
+{
+	char *p;
+	char *cmd;
+	unsigned int res;
+
+	/* unescape linebuffer */
+	cmd = utils_string_unescape(slave->linebuf);
+	if (strncmp(cmd, CMD_SEAMLESS_SPAWN " ", strlen(CMD_SEAMLESS_SPAWN) + 1) == 0)
+	{
+		/* process seamless spawn request */
+		p = strstr(cmd, "seamlessrdpshell.exe");
+		if (p)
+			p += strlen("seamlessrdpshell.exe") + 1;
+		else
+			p = cmd + strlen(CMD_SEAMLESS_SPAWN) + 1;
+
+		res = ERR_RESULT_OK;
+
+		if (seamless_send_spawn(p) == (unsigned int) -1)
+			res = 1;
+	}
+	else
+	{
+		res = ERR_RESULT_NO_SUCH_COMMAND;
+	}
+	xfree(cmd);
+
+	_ctrl_command_result(slave, res);
+}
+
+static RD_BOOL
+_ctrl_verify_unix_socket()
+{
+	int s, len;
+	struct sockaddr_un saun;
+
+	memset(&saun, 0, sizeof(struct sockaddr_un));
+
+	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+	{
+		perror("Error creating ctrl client socket: socket()");
+		exit(1);
+	}
+
+	saun.sun_family = AF_UNIX;
+	strcpy(saun.sun_path, ctrlsock_name);
+	len = sizeof(saun.sun_family) + strlen(saun.sun_path);
+
+	/* test connection */
+	if (connect(s, (struct sockaddr *) &saun, len) != 0)
+		return False;
+
+	shutdown(s, SHUT_RDWR);
+	close(s);
+	return True;
+}
+
+
+static void
+_ctrl_create_hash(const char *user, const char *domain, const char *host, char *hash, size_t hsize)
+{
+	RDSSL_SHA1 sha1;
+	uint8 out[20], delim;
+	uint16 version;
+	uint32 flags;
+
+	/* version\0user\0domain\0host\0flags */
+	flags = 0;
+	delim = '\0';
+	version = 0x0100;
+
+	if (g_seamless_rdp)
+		flags = CTRL_HASH_FLAG_SEAMLESS;
+
+	rdssl_sha1_init(&sha1);
+	rdssl_sha1_update(&sha1, (uint8 *) & version, sizeof(version));
+	rdssl_sha1_update(&sha1, &delim, 1);
+
+	if (user)
+		rdssl_sha1_update(&sha1, (uint8 *) user, strlen(user));
+	rdssl_sha1_update(&sha1, &delim, 1);
+
+	if (domain)
+		rdssl_sha1_update(&sha1, (uint8 *) domain, strlen(domain));
+	rdssl_sha1_update(&sha1, &delim, 1);
+
+	if (host)
+		rdssl_sha1_update(&sha1, (uint8 *) host, strlen(host));
+	rdssl_sha1_update(&sha1, &delim, 1);
+
+	rdssl_sha1_update(&sha1, (uint8 *) & flags, sizeof(flags));
+	rdssl_sha1_final(&sha1, out);
+
+	sec_hash_to_string(hash, hsize, out, sizeof(out));
+}
+
+
+/** Initialize ctrl
+    Ret values: <0 failure, 0 master, 1 client
+ */
+int
+ctrl_init(const char *user, const char *domain, const char *host)
+{
+	struct stat st;
+	struct sockaddr_un saun;
+	char hash[41], path[PATH_MAX];
+	char *home;
+
+	/* check if ctrl already initialized */
+	if (ctrlsock != 0 || _ctrl_is_slave)
+		return 0;
+
+	home = getenv("HOME");
+	if (home == NULL)
+	{
+		return -1;
+	}
+
+	/* get uniq hash for ctrlsock name */
+	_ctrl_create_hash(user, domain, host, hash, 41);
+	snprintf(ctrlsock_name, PATH_MAX, "%s" RDESKTOP_CTRLSOCK_STORE "/%s.ctl", home, hash);
+	ctrlsock_name[sizeof(ctrlsock_name) - 1] = '\0';
+
+	/* make sure that ctrlsock store path exists */
+	snprintf(path, PATH_MAX, "%s" RDESKTOP_CTRLSOCK_STORE, home);
+	path[sizeof(path) - 1] = '\0';
+	if (utils_mkdir_p(path, 0700) == -1)
+	{
+		perror(path);
+		return -1;
+	}
+
+	/* check if ctrl socket already exist then this process becomes a client */
+	if (stat(ctrlsock_name, &st) == 0)
+	{
+		/* verify that unix socket is not stale */
+		if (_ctrl_verify_unix_socket() == True)
+		{
+			_ctrl_is_slave = True;
+			return 1;
+		}
+		else
+		{
+			unlink(ctrlsock_name);
+		}
+	}
+
+	/* setup ctrl socket and start listening for connections */
+	if ((ctrlsock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+	{
+		perror("Error creating ctrl socket:");
+		exit(1);
+	}
+
+	/* bind and start listening on server socket */
+	memset(&saun, 0, sizeof(struct sockaddr_un));
+	saun.sun_family = AF_UNIX;
+	strncpy(saun.sun_path, ctrlsock_name, sizeof(saun.sun_path));
+	if (bind(ctrlsock, (struct sockaddr *) &saun, sizeof(struct sockaddr_un)) < 0)
+	{
+		perror("Error binding ctrl socket:");
+		exit(1);
+	}
+
+	if (listen(ctrlsock, 5) < 0)
+	{
+		perror("Error listening on socket:");
+		exit(1);
+	}
+
+	/* add ctrl cleanup func to exit hooks */
+	atexit(ctrl_cleanup);
+
+	return 0;
+}
+
+void
+ctrl_cleanup()
+{
+	if (ctrlsock)
+	{
+		close(ctrlsock);
+		unlink(ctrlsock_name);
+	}
+}
+
+RD_BOOL
+ctrl_is_slave()
+{
+	return _ctrl_is_slave;
+}
+
+
+void
+ctrl_add_fds(int *n, fd_set * rfds)
+{
+	_ctrl_slave_t *it;
+	if (ctrlsock == 0)
+		return;
+
+	FD_SET(ctrlsock, rfds);
+	*n = MAX(*n, ctrlsock);
+
+
+	/* add connected slaves to fd set */
+	it = _ctrl_slaves;
+	while (it)
+	{
+		FD_SET(it->sock, rfds);
+		*n = MAX(*n, it->sock);
+		it = it->next;
+	}
+}
+
+void
+ctrl_check_fds(fd_set * rfds, fd_set * wfds)
+{
+	int ns, res, offs;
+	struct sockaddr_un fsaun;
+	socklen_t fromlen;
+	_ctrl_slave_t *it;
+
+	if (ctrlsock == 0)
+		return;
+
+	memset(&fsaun, 0, sizeof(struct sockaddr_un));
+
+	/* check if we got any connections on server socket */
+	if (FD_ISSET(ctrlsock, rfds))
+	{
+		FD_CLR(ctrlsock, rfds);
+		fromlen = sizeof(fsaun);
+		ns = accept(ctrlsock, (struct sockaddr *) &fsaun, &fromlen);
+		if (ns < 0)
+		{
+			perror("server: accept()");
+			exit(1);
+		}
+
+		_ctrl_slave_new(ns);
+		return;
+	}
+
+	/* check if any of our slaves fds has data */
+	it = _ctrl_slaves;
+	while (it)
+	{
+		if (FD_ISSET(it->sock, rfds))
+		{
+			offs = strlen(it->linebuf);
+			res = recv(it->sock, it->linebuf + offs, CTRL_LINEBUF_SIZE - offs, 0);
+			FD_CLR(it->sock, rfds);
+
+			/* linebuffer full let's disconnect slave */
+			if (it->linebuf[CTRL_LINEBUF_SIZE - 1] != '\0' &&
+			    it->linebuf[CTRL_LINEBUF_SIZE - 1] != '\n')
+			{
+				_ctrl_slave_disconnect(it->sock);
+				break;
+			}
+
+			if (res > 0)
+			{
+				/* Check if we got full command line */
+				char *p;
+				if ((p = strchr(it->linebuf, '\n')) == NULL)
+					continue;
+
+				/* iterate over string and check against escaped \n */
+				while (p)
+				{
+					/* Check if newline is escaped */
+					if (p > it->linebuf && *(p - 1) != '\\')
+						break;
+					p = strchr(p + 1, '\n');
+				}
+
+				/* If we havent found an nonescaped \n we need more data */
+				if (p == NULL)
+					continue;
+
+				/* strip new linebuf and dispatch command */
+				*p = '\0';
+				_ctrl_dispatch_command(it);
+				memset(it->linebuf, 0, CTRL_LINEBUF_SIZE);
+			}
+			else
+			{
+				/* Peer disconnected or socket error */
+				_ctrl_slave_disconnect(it->sock);
+				break;
+			}
+		}
+		it = it->next;
+	}
+}
+
+#if HAVE_ICONV
+extern char g_codepage[16];
+#endif
+
+int
+ctrl_send_command(const char *cmd, const char *arg)
+{
+	FILE *fp;
+	struct sockaddr_un saun;
+	int s, len, index, ret;
+	char data[CTRL_LINEBUF_SIZE], tmp[CTRL_LINEBUF_SIZE];
+	char result[CTRL_RESULT_SIZE], c, *escaped;
+
+	escaped = NULL;
+
+	if (!_ctrl_is_slave)
+		return -1;
+
+	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+	{
+		perror("Error creating ctrl client socket: socket()");
+		exit(1);
+	}
+
+	memset(&saun, 0, sizeof(struct sockaddr_un));
+	saun.sun_family = AF_UNIX;
+	strcpy(saun.sun_path, ctrlsock_name);
+	len = sizeof(saun.sun_family) + strlen(saun.sun_path);
+
+	if (connect(s, (struct sockaddr *) &saun, len) < 0)
+	{
+		perror("Error connecting to ctrl socket: connect()");
+		exit(1);
+	}
+
+	/* Bundle cmd and argument into string, convert to UTF-8 if needed */
+	snprintf(data, CTRL_LINEBUF_SIZE, "%s %s", cmd, arg);
+	ret = utils_locale_to_utf8(data, strlen(data), tmp, CTRL_LINEBUF_SIZE - 1);
+
+	if (ret != 0)
+		goto bail_out;
+
+	/* escape the utf-8 string */
+	escaped = utils_string_escape(tmp);
+	if ((strlen(escaped) + 1) > CTRL_LINEBUF_SIZE - 1)
+		goto bail_out;
+
+	/* send escaped utf-8 command to master */
+	send(s, escaped, strlen(escaped), 0);
+	send(s, "\n", 1, 0);
+
+	/* read result from master */
+	fp = fdopen(s, "r");
+	index = 0;
+	while ((c = fgetc(fp)) != EOF && index < CTRL_RESULT_SIZE && c != '\n')
+	{
+		result[index] = c;
+		index++;
+	}
+	result[index - 1] = '\0';
+
+	if (strncmp(result, "ERROR ", 6) == 0)
+	{
+		if (sscanf(result, "ERROR %d", &ret) != 1)
+			ret = -1;
+	}
+
+      bail_out:
+	xfree(escaped);
+	shutdown(s, SHUT_RDWR);
+	close(s);
+
+	return ret;
+}
diff --git a/src/VBox/RDP/client/disk.c b/src/VBox/RDP/client-1.8.3/disk.c
similarity index 98%
rename from src/VBox/RDP/client/disk.c
rename to src/VBox/RDP/client-1.8.3/disk.c
index 3f8bd08..3ee26c8 100644
--- a/src/VBox/RDP/client/disk.c
+++ b/src/VBox/RDP/client-1.8.3/disk.c
@@ -125,6 +125,7 @@ struct dummy_statfs_t
 {
 	long f_bfree;
 	long f_bsize;
+	long f_bavail;
 	long f_blocks;
 	int f_namelen;
 	int f_namemax;
@@ -135,6 +136,7 @@ dummy_statfs(struct dummy_statfs_t *buf)
 {
 	buf->f_blocks = 262144;
 	buf->f_bfree = 131072;
+	buf->f_bavail = 131072;
 	buf->f_bsize = 512;
 	buf->f_namelen = 255;
 	buf->f_namemax = 255;
@@ -361,12 +363,13 @@ disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create
 	flags = 0;
 	mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
 
-	if (*filename && filename[strlen(filename) - 1] == '/')
+	if (filename && *filename && filename[strlen(filename) - 1] == '/')
 		filename[strlen(filename) - 1] = 0;
+
 #ifdef VBOX
 	snprintf(path, sizeof(path),  "%s%s", g_rdpdr_device[device_id].local_path, filename);
 #else
-	sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
+	sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename ? filename : "");
 #endif
 
 	/* Protect against mailicous servers:
@@ -727,7 +730,7 @@ RD_NTSTATUS
 disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
 {
 	uint32 length, file_attributes, ft_high, ft_low;
-	char newname[PATH_MAX], fullpath[PATH_MAX];
+	char *newname, fullpath[PATH_MAX];
 	struct fileinfo *pfinfo;
 	int mode;
 	struct stat filestat;
@@ -737,6 +740,7 @@ disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM ou
 
 	pfinfo = &(g_fileinfo[handle]);
 	g_notify_stamp = True;
+	newname = NULL;
 
 	switch (info_class)
 	{
@@ -826,15 +830,14 @@ disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM ou
 			in_uint8s(in, 0x1a);	/* unknown */
 			in_uint32_le(in, length);
 
-			if (length && (length / 2) < 256)
-			{
-				rdp_in_unistr(in, newname, sizeof(newname), length);
-				convert_to_unix_filename(newname);
-			}
-			else
-			{
+			if (length && (length / 2) >= 256)
 				return RD_STATUS_INVALID_PARAMETER;
-			}
+
+			rdp_in_unistr(in, length, &newname, &length);
+			if (newname == NULL)
+				return RD_STATUS_INVALID_PARAMETER;
+
+			convert_to_unix_filename(newname);
 
 #ifdef VBOX
 			snprintf(fullpath, sizeof(fullpath), "%s%s", g_rdpdr_device[pfinfo->device_id].local_path,
@@ -844,6 +847,8 @@ disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM ou
 				newname);
 #endif
 
+			free(newname);
+
 			if (rename(pfinfo->path, fullpath) != 0)
 			{
 				perror("rename");
@@ -1155,7 +1160,7 @@ disk_query_volume_information(RD_NTHANDLE handle, uint32 info_class, STREAM out)
 
 			out_uint32_le(out, stat_fs.f_blocks);	/* Total allocation units low */
 			out_uint32_le(out, 0);	/* Total allocation units high */
-			out_uint32_le(out, stat_fs.f_blocks);	/* Caller allocation units low */
+			out_uint32_le(out, stat_fs.f_bavail);	/* Caller allocation units low */
 			out_uint32_le(out, 0);	/* Caller allocation units high */
 			out_uint32_le(out, stat_fs.f_bfree);	/* Available allocation units */
 			out_uint32_le(out, 0);	/* Available allowcation units */
@@ -1210,7 +1215,7 @@ disk_query_directory(RD_NTHANDLE handle, uint32 info_class, char *pattern, STREA
 		case FileNamesInformation:
 
 			/* If a search pattern is received, remember this pattern, and restart search */
-			if (pattern[0] != 0)
+			if (pattern != NULL && pattern[0] != 0)
 			{
 				strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), PATH_MAX - 1);
 				rewinddir(pdir);
@@ -1386,8 +1391,13 @@ disk_query_directory(RD_NTHANDLE handle, uint32 info_class, char *pattern, STREA
 static RD_NTSTATUS
 disk_device_control(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out)
 {
+#ifdef VBOX
+	if (((request >> 16) != 20) && ((request >> 16) != 9))
+		return RD_STATUS_INVALID_PARAMETER;
+#else
 	if (((request >> 16) != 20) || ((request >> 16) != 9))
 		return RD_STATUS_INVALID_PARAMETER;
+#endif
 
 	/* extract operation */
 	request >>= 2;
diff --git a/src/VBox/RDP/client/disk.h b/src/VBox/RDP/client-1.8.3/disk.h
similarity index 100%
rename from src/VBox/RDP/client/disk.h
rename to src/VBox/RDP/client-1.8.3/disk.h
diff --git a/src/VBox/RDP/client/doc/AUTHORS b/src/VBox/RDP/client-1.8.3/doc/AUTHORS
similarity index 100%
rename from src/VBox/RDP/client/doc/AUTHORS
rename to src/VBox/RDP/client-1.8.3/doc/AUTHORS
diff --git a/src/VBox/RDP/client/doc/ChangeLog b/src/VBox/RDP/client-1.8.3/doc/ChangeLog
similarity index 58%
rename from src/VBox/RDP/client/doc/ChangeLog
rename to src/VBox/RDP/client-1.8.3/doc/ChangeLog
index 2531440..351442a 100644
--- a/src/VBox/RDP/client/doc/ChangeLog
+++ b/src/VBox/RDP/client-1.8.3/doc/ChangeLog
@@ -1,3 +1,80 @@
+rdesktop (1.8.3)
+  * Added a persistent mode used with SeamlessRDP
+  * Added US international keyboard layout with dead keys
+  * Code cleanup to match specifications, use constants defined
+    instead of magic numbers, remove of dead code
+  * Fix regression with failed connection and a invalid licensing
+    message, introduced in 1.8.2
+  * Fix issue with Non ASCII user / password when using CredSSP
+  * Fix issues using smartcard redirection with Windows 2012 R2
+  * Fix issue with windows key functionality
+  * Fix memory corruption when using rdp_out_unistr()
+  * Fix workaround for the lack of support for alpha cursors
+  * Fix silent exit when redirected when using CredSSP
+  * Fix crash when starting rdesktop without domain specified
+    while using CredSSP
+  * Fix issue in SeamlessRDP protocol parser upon reconnect
+  * Fix issue were a new SeamlessRDP application is respawned
+    upon a reconnection
+
+  -- Henrik Andersson <hean01 at users.sourceforge.net> 2014-10-31
+
+rdesktop (1.8.2)
+  * Support enhanced server redirection (Session broker 2012)
+  * Support License Error Alert PDU
+  * Changed default driver for printer redirection
+  * Fix CredSSP login using non-ASCII username/password
+  * Fix double login prompt bug with Win2008 server redirection
+  * Fix keysym collisions
+  * Fix mouse cursor with 2012 R2
+  * Fix local drive redirection with Win8 / Win2012
+  * Fix issue with mouse cursor hotspot
+  * Fix issue with mouse / keyboard against VirtualBox RDP
+  * Fix uncomplete czech keymap
+  * Fix error in dutch keymap
+
+  -- Henrik Andersson <hean01 at users.sourceforge.net> 2014-05-20
+
+rdesktop (1.8.1)
+  * Fix a typo in configure.ac
+  * Fix a bug which made rdesktop steal CPU cycles.
+  * Fix issue with reconnect, make use of deactivate variable
+  * Added 4 new disconnect reasons with exit codes
+  * Fix issues of window handling in SeamlessRDP parts of rdesktop
+  * Fix a backward compability with OpenSSL < 0.9.9
+  * Fix a bug when code needs a x window available but there are none.
+  * Fix a sigsegv zeroing memory
+  * Fix a 64bit portability issue
+
+  -- Henrik Andersson <hean01 at users.sourceforge.net> 2013-11-18
+
+rdesktop (1.8.0)
+  * Support for protocol negotiation eg. SSL/TLSv1 and CredSSP
+  * Support for CredSSP + Kerberos authentication (NLA)
+  * Support for smart card single-sign-on
+  * Support passing smart card pin as password as argument
+  * Added IPC for controlling a master rdesktop process
+  * Support for connection sharing when using SeamlessRDP
+  * Improved handling of network connection failures
+  * Autoreconnect using the connection cookie at network failure
+  * Fix a few smart card issues
+  * Fix bug with mouse scroll handling
+  * Fix for left/right braces in Italian keymap
+  * Fix crash and memory leak in local drive redirection
+  * Fixes issues with license files loading/saving
+
+  -- Henrik Andersson <hean01 at users.sourceforge.net> 2013-08-09
+
+rdesktop (1.7.1)
+  * Fix clipboard issue when not building with unicode support
+  * Fix compilation against newer PCSC lite versions
+  * Fix for per-device license mode on Windows 2008 R2 terminal server
+  * Fix building 64bit version with static openssl linkage
+  * Rewrite of smartcard handling for 64bit support, fixes several bugs
+  * Improved license handling using XDG directories
+
+  -- Henrik Andersson <hean01 at users.sourceforge.net> 2012-01-09
+
 rdesktop (1.7.0)
   * Security: Directory traversal vulnerability with disk redirection (disallow /.. requests)
   * New maintainer: Peter Åstrand <astrand at cendio.se>
diff --git a/src/VBox/RDP/client/doc/HACKING b/src/VBox/RDP/client-1.8.3/doc/HACKING
similarity index 100%
rename from src/VBox/RDP/client/doc/HACKING
rename to src/VBox/RDP/client-1.8.3/doc/HACKING
diff --git a/src/VBox/RDP/client/doc/TODO b/src/VBox/RDP/client-1.8.3/doc/TODO
similarity index 100%
rename from src/VBox/RDP/client/doc/TODO
rename to src/VBox/RDP/client-1.8.3/doc/TODO
diff --git a/src/VBox/RDP/client/doc/ipv6.txt b/src/VBox/RDP/client-1.8.3/doc/ipv6.txt
similarity index 100%
rename from src/VBox/RDP/client/doc/ipv6.txt
rename to src/VBox/RDP/client-1.8.3/doc/ipv6.txt
diff --git a/src/VBox/RDP/client/doc/keymap-names.txt b/src/VBox/RDP/client-1.8.3/doc/keymap-names.txt
similarity index 100%
rename from src/VBox/RDP/client/doc/keymap-names.txt
rename to src/VBox/RDP/client-1.8.3/doc/keymap-names.txt
diff --git a/src/VBox/RDP/client/doc/keymapping.txt b/src/VBox/RDP/client-1.8.3/doc/keymapping.txt
similarity index 100%
rename from src/VBox/RDP/client/doc/keymapping.txt
rename to src/VBox/RDP/client-1.8.3/doc/keymapping.txt
diff --git a/src/VBox/RDP/client/doc/licensing.txt b/src/VBox/RDP/client-1.8.3/doc/licensing.txt
similarity index 100%
rename from src/VBox/RDP/client/doc/licensing.txt
rename to src/VBox/RDP/client-1.8.3/doc/licensing.txt
diff --git a/src/VBox/RDP/client/doc/patches.txt b/src/VBox/RDP/client-1.8.3/doc/patches.txt
similarity index 100%
rename from src/VBox/RDP/client/doc/patches.txt
rename to src/VBox/RDP/client-1.8.3/doc/patches.txt
diff --git a/src/VBox/RDP/client/doc/rdesktop.1 b/src/VBox/RDP/client-1.8.3/doc/rdesktop.1
similarity index 80%
rename from src/VBox/RDP/client/doc/rdesktop.1
rename to src/VBox/RDP/client-1.8.3/doc/rdesktop.1
index 95f97d3..f6c5207 100644
--- a/src/VBox/RDP/client/doc/rdesktop.1
+++ b/src/VBox/RDP/client-1.8.3/doc/rdesktop.1
@@ -20,7 +20,8 @@ Username for authentication on the server.
 Domain for authentication.
 .TP
 .BR "-s <shell>"
-Startup shell for the user - starts a specific application instead of Explorer.
+Startup shell for the user - starts a specific application instead of Explore.
+If SeamlessRDP is enabled this is the application which i started in seamless mode.
 .TP
 .BR "-c <directory>"
 The initial working directory for the user.  Often used in combination with -s
@@ -72,6 +73,11 @@ size is changed, rdesktop will automatically reconnect using the new
 screen size. This requires that rdesktop has been compiled with RandR
 support.
 .TP
+.BR "-i"
+Use password as smartcard pin. If a valid user certificate is matched in smart card
+reader the password passed with \f-p\fR argument is used as pin for the smart card.
+This feature also requires that smart card redirection is used using \f-r scard\fR argument.
+.TP
 .BR "-f"
 Enable fullscreen mode.  This overrides the window manager and causes the
 rdesktop window to fully cover the current screen.  Fullscreen mode can be
@@ -81,15 +87,25 @@ toggled at any time using Ctrl-Alt-Enter.
 Force the server to send screen updates as bitmaps rather than using
 higher-level drawing operations.
 .TP
-.BR "-A"
-Enable SeamlessRDP. In this mode, rdesktop creates a X11 window for
-each window on the server side. This mode requires the SeamlessRDP
-server side component, which is available from 
+.BR "-t"
+Disable use of remote control. This will disable features like seamless connection
+sharing.
+.TP
+.BR "-A <seamlessrdpshell>"
+Enable SeamlessRDP by specifying the path to seamless rdp shell. 
+In this mode, rdesktop creates a X11 window for each window on the server side. 
+This mode requires the SeamlessRDP server side component, which is available from 
 \fIhttp://www.cendio.com/seamlessrdp/\fR.
-When using this option, you should specify a startup shell which
+
+When using this option, you should normally specify a startup shell which
 launches the desired application through SeamlessRDP. 
 
-Example: rdesktop -A -s 'seamlessrdpshell notepad'.
+Example: rdesktop -A 'c:\\seamlessrdp\\seamlessrdpshell.exe' -s 'notepad' mywts.domain.com
+
+Any subsequential call to the above commandline example will make use of the seamless 
+connection sharing feature which spawns another notepad in the current connection to the
+specified server and then exit.
+
 .TP
 .BR "-B"
 Use the BackingStore of the Xserver instead of the integrated one in
@@ -139,7 +155,7 @@ Embed rdesktop-window in another window. The windowid is expected to
 be decimal or hexadecimal (prefixed by 0x).
 .TP
 .BR "-a <bpp>"
-Sets the colour depth for the connection (8, 15, 16 or 24).
+Sets the colour depth for the connection (8, 15, 16, 24 or 32).
 More than 8 bpp are only supported when connecting to Windows XP
 (up to 16 bpp) or newer.  Note that the colour depth may also be
 limited by the server configuration. The default value is the depth 
@@ -161,8 +177,8 @@ number containing the flags.
 Enable caching of bitmaps to disk (persistent bitmap caching). This generally
 improves performance (especially on low bandwidth connections) and reduces
 network traffic at the cost of slightly longer startup and some disk space.
-(10MB for 8-bit colour, 20MB for 15/16-bit colour and 30MB for 24-bit colour
-sessions)
+(10MB for 8-bit colour, 20MB for 15/16-bit colour, 30MB for 24-bit colour
+and 40MB for 32-bit colour sessions)
 .TP
 .BR "-r <device>"
 Enable redirection of the specified device on the client, such
@@ -225,6 +241,27 @@ Use RDP version 4.
 .BR "-5"
 Use RDP version 5 (default).
 .PP
+
+.SH "CredSSP Smartcard options"
+.TP
+.BR "--sc-csp-name <name>"
+Specify the CSP (Crypto Service Provider) to use on the windows side for the smartcard
+authentication. CSP is the driver for your smartcard and it seems like this is required
+to be specified for CredSSP authentication. For swedish NetID the following CSP name is
+used; "Net iD - CSP".
+.TP
+.BR "--sc-container-name <name>"
+Specify the container name, usally this is the username for default container and it seems
+like this is required to be specified for CredSSP authentication.
+.TP
+.BR "--sc-reader-name <name>"
+Specify the reader name to be used to prevent the pin code being sent to wrong card if there
+are several readers.
+.TP
+.BR "--sc-card-name <name>"
+Specify the card name for example; "Telia EID IP5a".
+.PP
+
 .SH "EXIT VALUES"
 .PP 
 .IP "\fB0\fP"
@@ -245,6 +282,16 @@ The server is out of memory
 The server denied the connection
 .IP "\fB8\fP"
 The server denied the connection for security reason
+.IP "\fB9\fP"
+The user cannot connect to the server due to insufficient access
+privileges
+.IP "\fB10\fP"
+The server does not accept saved user credentials and requires that
+the user enter their credentials for each connection
+.IP "\fB11\fP"
+Disconnect initiated by administration tool
+.IP "\fB12\fP"
+Disconnect initiated by user
 .IP "\fB16\fP"
 Internal licensing error
 .IP "\fB17\fP"
diff --git a/src/VBox/RDP/client/doc/redirection.txt b/src/VBox/RDP/client-1.8.3/doc/redirection.txt
similarity index 100%
rename from src/VBox/RDP/client/doc/redirection.txt
rename to src/VBox/RDP/client-1.8.3/doc/redirection.txt
diff --git a/src/VBox/RDP/client/ewmhints.c b/src/VBox/RDP/client-1.8.3/ewmhints.c
similarity index 95%
rename from src/VBox/RDP/client/ewmhints.c
rename to src/VBox/RDP/client-1.8.3/ewmhints.c
index 03f6140..8590f92 100644
--- a/src/VBox/RDP/client/ewmhints.c
+++ b/src/VBox/RDP/client-1.8.3/ewmhints.c
@@ -212,7 +212,7 @@ ewmh_get_window_state(Window w)
 {
 	unsigned long nitems_return;
 	unsigned char *prop_return;
-	uint32 *return_words;
+	unsigned long *return_words;
 	unsigned long item;
 	RD_BOOL maximized_vert, maximized_horz, hidden;
 
@@ -221,7 +221,7 @@ ewmh_get_window_state(Window w)
 	if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return, 0) < 0)
 		return SEAMLESSRDP_NORMAL;
 
-	return_words = (uint32 *) prop_return;
+	return_words = (unsigned long *) prop_return;
 
 	for (item = 0; item < nitems_return; item++)
 	{
@@ -235,10 +235,11 @@ ewmh_get_window_state(Window w)
 
 	XFree(prop_return);
 
-	if (maximized_vert && maximized_horz)
-		return SEAMLESSRDP_MAXIMIZED;
-	else if (hidden)
+	/* In EWMH, HIDDEN overrides MAXIMIZED_VERT/MAXIMIZED_HORZ */
+	if (hidden)
 		return SEAMLESSRDP_MINIMIZED;
+	else if (maximized_vert && maximized_horz)
+		return SEAMLESSRDP_MAXIMIZED;
 	else
 		return SEAMLESSRDP_NORMAL;
 }
@@ -551,6 +552,33 @@ ewmh_set_window_above(Window wnd)
 	return 0;
 }
 
+RD_BOOL
+ewmh_is_window_above(Window w)
+{
+	unsigned long nitems_return;
+	unsigned char *prop_return;
+	unsigned long *return_words;
+	unsigned long item;
+	RD_BOOL above;
+
+	above = False;
+
+	if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return, 0) < 0)
+		return False;
+
+	return_words = (unsigned long *) prop_return;
+
+	for (item = 0; item < nitems_return; item++)
+	{
+		if (return_words[item] == g_net_wm_state_above_atom)
+			above = True;
+	}
+
+	XFree(prop_return);
+
+	return above;
+}
+
 #endif /* MAKE_PROTO */
 
 
diff --git a/src/VBox/RDP/client/install-sh b/src/VBox/RDP/client-1.8.3/install-sh
similarity index 100%
rename from src/VBox/RDP/client/install-sh
rename to src/VBox/RDP/client-1.8.3/install-sh
diff --git a/src/VBox/RDP/client/iso.c b/src/VBox/RDP/client-1.8.3/iso.c
similarity index 51%
rename from src/VBox/RDP/client/iso.c
rename to src/VBox/RDP/client-1.8.3/iso.c
index dfa05f6..740b45f 100644
--- a/src/VBox/RDP/client/iso.c
+++ b/src/VBox/RDP/client-1.8.3/iso.c
@@ -3,6 +3,7 @@
    Protocol services - ISO layer
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
    Copyright 2005-2011 Peter Astrand <astrand at cendio.se> for Cendio AB
+   Copyright 2012 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -29,6 +30,19 @@
 
 #include "rdesktop.h"
 
+extern RD_BOOL g_encryption;
+extern RD_BOOL g_encryption_initial;
+extern RDP_VERSION g_rdp_version;
+extern RD_BOOL g_use_password_as_pin;
+
+static RD_BOOL g_negotiate_rdp_protocol = True;
+
+extern char *g_sc_csp_name;
+extern char *g_sc_reader_name;
+extern char *g_sc_card_name;
+extern char *g_sc_container_name;
+
+
 /* Send a self-contained ISO PDU */
 static void
 iso_send_msg(uint8 code)
@@ -52,11 +66,14 @@ iso_send_msg(uint8 code)
 }
 
 static void
-iso_send_connection_request(char *username)
+iso_send_connection_request(char *username, uint32 neg_proto)
 {
 	STREAM s;
 	int length = 30 + strlen(username);
 
+	if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
+		length += 8;
+
 	s = tcp_init(length);
 
 	out_uint8(s, 3);	/* version */
@@ -72,8 +89,17 @@ iso_send_connection_request(char *username)
 	out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash="));
 	out_uint8p(s, username, strlen(username));
 
-	out_uint8(s, 0x0d);	/* Unknown */
-	out_uint8(s, 0x0a);	/* Unknown */
+	out_uint8(s, 0x0d);	/* cookie termination string: CR+LF */
+	out_uint8(s, 0x0a);
+
+	if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
+	{
+		/* optional rdp protocol negotiation request for RDPv5 */
+		out_uint8(s, RDP_NEG_REQ);
+		out_uint8(s, 0);
+		out_uint16(s, 8);
+		out_uint32(s, neg_proto);
+	}
 
 	s_mark_end(s);
 	tcp_send(s);
@@ -183,23 +209,37 @@ iso_recv(uint8 * rdpver)
 
 /* Establish a connection up to the ISO layer */
 RD_BOOL
-iso_connect(char *server, char *username, RD_BOOL reconnect)
+iso_connect(char *server, char *username, char *domain, char *password,
+	    RD_BOOL reconnect, uint32 * selected_protocol)
 {
-	uint8 code = 0;
+	STREAM s;
+	uint8 code;
+	uint32 neg_proto;
+
+	g_negotiate_rdp_protocol = True;
+
+	neg_proto = PROTOCOL_SSL;
+
+#ifdef WITH_CREDSSP
+	if (!g_use_password_as_pin)
+		neg_proto |= PROTOCOL_HYBRID;
+	else if (g_sc_csp_name || g_sc_reader_name || g_sc_card_name || g_sc_container_name)
+		neg_proto |= PROTOCOL_HYBRID;
+	else
+		warning("Disables CredSSP due to missing smartcard information for SSO.\n");
+#endif
+
+      retry:
+	*selected_protocol = PROTOCOL_RDP;
+	code = 0;
 
 	if (!tcp_connect(server))
 		return False;
 
-	if (reconnect)
-	{
-		iso_send_msg(ISO_PDU_CR);
-	}
-	else
-	{
-		iso_send_connection_request(username);
-	}
+	iso_send_connection_request(username, neg_proto);
 
-	if (iso_recv_msg(&code, NULL) == NULL)
+	s = iso_recv_msg(&code, NULL);
+	if (s == NULL)
 		return False;
 
 	if (code != ISO_PDU_CC)
@@ -209,6 +249,115 @@ iso_connect(char *server, char *username, RD_BOOL reconnect)
 		return False;
 	}
 
+	if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8))
+	{
+		/* handle RDP_NEG_REQ response */
+		const char *reason = NULL;
+
+		uint8 type = 0, flags = 0;
+		uint16 length = 0;
+		uint32 data = 0;
+
+		in_uint8(s, type);
+		in_uint8(s, flags);
+		in_uint16(s, length);
+		in_uint32(s, data);
+
+		if (type == RDP_NEG_FAILURE)
+		{
+			RD_BOOL retry_without_neg = False;
+
+			switch (data)
+			{
+				case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
+					reason = "SSL with user authentication required by server";
+					break;
+				case SSL_NOT_ALLOWED_BY_SERVER:
+					reason = "SSL not allowed by server";
+					retry_without_neg = True;
+					break;
+				case SSL_CERT_NOT_ON_SERVER:
+					reason = "no valid authentication certificate on server";
+					retry_without_neg = True;
+					break;
+				case INCONSISTENT_FLAGS:
+					reason = "inconsistent negotiation flags";
+					break;
+				case SSL_REQUIRED_BY_SERVER:
+					reason = "SSL required by server";
+					break;
+				case HYBRID_REQUIRED_BY_SERVER:
+					reason = "CredSSP required by server";
+					break;
+				default:
+					reason = "unknown reason";
+			}
+
+			tcp_disconnect();
+
+			if (retry_without_neg)
+			{
+				fprintf(stderr,
+					"Failed to negotiate protocol, retrying with plain RDP.\n");
+				g_negotiate_rdp_protocol = False;
+				goto retry;
+			}
+
+			fprintf(stderr, "Failed to connect, %s.\n", reason);
+			return False;
+		}
+
+		if (type != RDP_NEG_RSP)
+		{
+			tcp_disconnect();
+			error("Expected RDP_NEG_RSP, got type = 0x%x\n", type);
+			return False;
+		}
+
+		/* handle negotiation response */
+		if (data == PROTOCOL_SSL)
+		{
+			if (!tcp_tls_connect())
+			{
+				/* failed to connect using cssp, let retry with plain TLS */
+				tcp_disconnect();
+				neg_proto = PROTOCOL_RDP;
+				goto retry;
+			}
+			/* do not use encryption when using TLS */
+			g_encryption = False;
+			fprintf(stderr, "Connection established using SSL.\n");
+		}
+#ifdef WITH_CREDSSP
+		else if (data == PROTOCOL_HYBRID)
+		{
+			if (!cssp_connect(server, username, domain, password, s))
+			{
+				/* failed to connect using cssp, let retry with plain TLS */
+				tcp_disconnect();
+				neg_proto = PROTOCOL_SSL;
+				goto retry;
+			}
+
+			/* do not use encryption when using TLS */
+			fprintf(stderr, "Connection established using CredSSP.\n");
+			g_encryption = False;
+		}
+#endif
+		else if (data == PROTOCOL_RDP)
+		{
+			fprintf(stderr, "Connection established using plain RDP.\n");
+		}
+		else if (data != PROTOCOL_RDP)
+		{
+			tcp_disconnect();
+			error("Unexpected protocol in negotiation response, got data = 0x%x.\n",
+			      data);
+			return False;
+		}
+
+		*selected_protocol = data;
+	}
 	return True;
 }
 
@@ -224,5 +373,6 @@ iso_disconnect(void)
 void
 iso_reset_state(void)
 {
+	g_encryption = g_encryption_initial;
 	tcp_reset_state();
 }
diff --git a/src/VBox/RDP/client/keymaps/ar b/src/VBox/RDP/client-1.8.3/keymaps/ar
similarity index 100%
rename from src/VBox/RDP/client/keymaps/ar
rename to src/VBox/RDP/client-1.8.3/keymaps/ar
diff --git a/src/VBox/RDP/client/keymaps/common b/src/VBox/RDP/client-1.8.3/keymaps/common
similarity index 100%
rename from src/VBox/RDP/client/keymaps/common
rename to src/VBox/RDP/client-1.8.3/keymaps/common
diff --git a/src/VBox/RDP/client/keymaps/convert-map b/src/VBox/RDP/client-1.8.3/keymaps/convert-map
similarity index 96%
rename from src/VBox/RDP/client/keymaps/convert-map
rename to src/VBox/RDP/client-1.8.3/keymaps/convert-map
index c88c72d..d5c1eae 100755
--- a/src/VBox/RDP/client/keymaps/convert-map
+++ b/src/VBox/RDP/client-1.8.3/keymaps/convert-map
@@ -1,8 +1,7 @@
 #!/usr/bin/env python2
 # -*-Python-*-
 #
-# 
-# Copyright (C) 2001  Peter Åstrand <astrand at cendio.se>
+# Copyright 2001 Peter Åstrand <astrand at cendio.se> for Cendio AB
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/src/VBox/RDP/client-1.8.3/keymaps/cs b/src/VBox/RDP/client-1.8.3/keymaps/cs
new file mode 100644
index 0000000..ee3a8e3
--- /dev/null
+++ b/src/VBox/RDP/client-1.8.3/keymaps/cs
@@ -0,0 +1,187 @@
+#Czech keymap
+#2007-05-28 by Jaroslav Jiricka <giahra at atlas.cz>
+include common
+
+#Additional sequences
+#2007-05-28 by Jaroslav Jiricka <giahra at atlas.cz>
+
+sequence ecaron dead_caron e
+sequence Ecaron dead_caron E
+sequence eogonek dead_ogonek e
+sequence Eogonek dead_ogonek E
+
+sequence rcaron dead_caron r
+sequence Rcaron dead_caron R
+sequence racute dead_acute r
+sequence Racute dead_acute R
+
+sequence tcaron dead_caron t
+sequence Tcaron dead_caron T
+sequence tcedilla dead_cedilla t
+sequence Tcedilla dead_cedilla T
+
+sequence zcaron dead_caron z
+sequence Zcaron dead_caron Z
+sequence zacute dead_acute z
+sequence Zacute dead_acute Z
+sequence zabovedot dead_abovedot z
+sequence Zabovedot dead_abovedot Z
+
+sequence uring dead_abovering u
+sequence Uring dead_abovering U
+sequence udoubleacute dead_doubleacute u
+sequence Udoubleacute dead_doubleacute U
+
+sequence odoubleacute dead_doubleacute o
+sequence Odoubleacute dead_doubleacute O
+
+sequence aogonek dead_ogonek a
+sequence Aogonek dead_ogonek A
+sequence abreve dead_breve a
+sequence Abreve dead_breve A
+
+sequence scaron dead_caron s
+sequence Scaron dead_caron S
+sequence sacute dead_acute s
+sequence Sacute dead_acute S
+sequence scedilla dead_cedilla s
+sequence Scedilla dead_cedilla S
+
+sequence dcaron dead_caron d
+sequence Dcaron dead_caron D
+
+sequence gbreve dead_breve g
+sequence Gbreve dead_breve G
+
+sequence lcaron dead_caron l
+sequence Lcaron dead_caron L
+sequence lacute dead_acute l
+sequence Lacute dead_acute L
+
+sequence ccaron dead_caron c
+sequence Ccaron dead_caron C
+
+sequence ncaron dead_caron n
+sequence Ncaron dead_caron N
+sequence nacute dead_acute n
+sequence Nacute dead_acute N
+#Additional sequences end
+
+map 0x405
+
+semicolon 0x29
+dead_abovering 0x29 shift
+
+plus 0x02
+1 0x02 shift
+dead_tilde 0x02 altgr
+asciitilde 0x02 altgr
+
+ecaron 0x03
+2 0x03 shift
+dead_caron 0x03 altgr
+
+scaron 0x04
+3 0x04 shift
+dead_circumflex 0x04 altgr
+
+ccaron 0x05
+4 0x05 shift
+dead_breve 0x05 altgr
+
+rcaron 0x06
+5 0x06 shift
+dead_abovering 0x06 altgr
+
+zcaron 0x07
+6 0x07 shift
+dead_ogonek 0x07 altgr
+
+yacute 0x08
+7 0x08 shift
+dead_grave 0x08 altgr
+
+aacute 0x09
+8 0x09 shift
+dead_abovedot 0x08 altgr
+
+iacute 0x0a
+9 0x0a shift
+dead_acute 0x08 altgr
+
+eacute 0x0b
+0 0x0b shift
+dead_doubleacute 0x0b altgr
+
+equal 0x0c
+percent 0x0c shift
+dead_macron 0x0c altgr
+
+dead_acute 0x0d
+dead_caron 0x0d shift
+dead_cedilla 0x0d altgr
+
+backslash 0x10 altgr
+
+bar 0x11 altgr
+
+EuroSign 0x12 altgr
+
+z 0x15 addupper
+
+uacute 0x1a
+slash 0x1a shift
+division 0x1a altgr
+
+parenright 0x1b
+parenleft 0x1b shift
+multiply 0x1b altgr
+
+dead_diaeresis 0x2b
+apostrophe 0x2b shift
+currency 0x2b altgr
+
+dstroke 0x1f altgr
+
+Dstroke 0x20 altgr
+
+bracketleft 0x21 altgr
+
+bracketright 0x22 altgr
+
+lstroke 0x25 altgr
+
+Lstroke 0x26 altgr
+
+uring 0x27
+quotedbl 0x27 shift
+dollar 0x27 altgr
+
+section 0x28
+exclam 0x28 shift
+ssharp 0x28 altgr
+
+y 0x2c addupper
+
+numbersign 0x2d altgr
+
+ampersand 0x2e altgr
+
+at 0x2f altgr
+
+braceleft 0x30 altgr
+
+braceright 0x31 altgr
+
+comma 0x33
+question 0x33 shift
+less 0x33 altgr
+
+period 0x34
+colon 0x34 shift
+greater 0x34 altgr
+
+minus 0x35
+underscore 0x35 shift
+asterisk 0x35 altgr
+
diff --git a/src/VBox/RDP/client/keymaps/da b/src/VBox/RDP/client-1.8.3/keymaps/da
similarity index 100%
rename from src/VBox/RDP/client/keymaps/da
rename to src/VBox/RDP/client-1.8.3/keymaps/da
diff --git a/src/VBox/RDP/client/keymaps/de b/src/VBox/RDP/client-1.8.3/keymaps/de
similarity index 100%
rename from src/VBox/RDP/client/keymaps/de
rename to src/VBox/RDP/client-1.8.3/keymaps/de
diff --git a/src/VBox/RDP/client/keymaps/de-ch b/src/VBox/RDP/client-1.8.3/keymaps/de-ch
similarity index 100%
rename from src/VBox/RDP/client/keymaps/de-ch
rename to src/VBox/RDP/client-1.8.3/keymaps/de-ch
diff --git a/src/VBox/RDP/client/keymaps/en-dv b/src/VBox/RDP/client-1.8.3/keymaps/en-dv
similarity index 100%
rename from src/VBox/RDP/client/keymaps/en-dv
rename to src/VBox/RDP/client-1.8.3/keymaps/en-dv
diff --git a/src/VBox/RDP/client/keymaps/en-gb b/src/VBox/RDP/client-1.8.3/keymaps/en-gb
similarity index 100%
rename from src/VBox/RDP/client/keymaps/en-gb
rename to src/VBox/RDP/client-1.8.3/keymaps/en-gb
diff --git a/src/VBox/RDP/client/keymaps/en-us b/src/VBox/RDP/client-1.8.3/keymaps/en-us
similarity index 100%
rename from src/VBox/RDP/client/keymaps/en-us
rename to src/VBox/RDP/client-1.8.3/keymaps/en-us
diff --git a/src/VBox/RDP/client/keymaps/es b/src/VBox/RDP/client-1.8.3/keymaps/es
similarity index 100%
rename from src/VBox/RDP/client/keymaps/es
rename to src/VBox/RDP/client-1.8.3/keymaps/es
diff --git a/src/VBox/RDP/client/keymaps/et b/src/VBox/RDP/client-1.8.3/keymaps/et
similarity index 100%
rename from src/VBox/RDP/client/keymaps/et
rename to src/VBox/RDP/client-1.8.3/keymaps/et
diff --git a/src/VBox/RDP/client/keymaps/fi b/src/VBox/RDP/client-1.8.3/keymaps/fi
similarity index 100%
rename from src/VBox/RDP/client/keymaps/fi
rename to src/VBox/RDP/client-1.8.3/keymaps/fi
diff --git a/src/VBox/RDP/client/keymaps/fo b/src/VBox/RDP/client-1.8.3/keymaps/fo
similarity index 100%
rename from src/VBox/RDP/client/keymaps/fo
rename to src/VBox/RDP/client-1.8.3/keymaps/fo
diff --git a/src/VBox/RDP/client/keymaps/fr b/src/VBox/RDP/client-1.8.3/keymaps/fr
similarity index 100%
rename from src/VBox/RDP/client/keymaps/fr
rename to src/VBox/RDP/client-1.8.3/keymaps/fr
diff --git a/src/VBox/RDP/client/keymaps/fr-be b/src/VBox/RDP/client-1.8.3/keymaps/fr-be
similarity index 100%
rename from src/VBox/RDP/client/keymaps/fr-be
rename to src/VBox/RDP/client-1.8.3/keymaps/fr-be
diff --git a/src/VBox/RDP/client/keymaps/fr-ca b/src/VBox/RDP/client-1.8.3/keymaps/fr-ca
similarity index 100%
rename from src/VBox/RDP/client/keymaps/fr-ca
rename to src/VBox/RDP/client-1.8.3/keymaps/fr-ca
diff --git a/src/VBox/RDP/client/keymaps/fr-ch b/src/VBox/RDP/client-1.8.3/keymaps/fr-ch
similarity index 100%
rename from src/VBox/RDP/client/keymaps/fr-ch
rename to src/VBox/RDP/client-1.8.3/keymaps/fr-ch
diff --git a/src/VBox/RDP/client/keymaps/he b/src/VBox/RDP/client-1.8.3/keymaps/he
similarity index 100%
rename from src/VBox/RDP/client/keymaps/he
rename to src/VBox/RDP/client-1.8.3/keymaps/he
diff --git a/src/VBox/RDP/client/keymaps/hr b/src/VBox/RDP/client-1.8.3/keymaps/hr
similarity index 100%
rename from src/VBox/RDP/client/keymaps/hr
rename to src/VBox/RDP/client-1.8.3/keymaps/hr
diff --git a/src/VBox/RDP/client/keymaps/hu b/src/VBox/RDP/client-1.8.3/keymaps/hu
similarity index 100%
rename from src/VBox/RDP/client/keymaps/hu
rename to src/VBox/RDP/client-1.8.3/keymaps/hu
diff --git a/src/VBox/RDP/client/keymaps/is b/src/VBox/RDP/client-1.8.3/keymaps/is
similarity index 100%
rename from src/VBox/RDP/client/keymaps/is
rename to src/VBox/RDP/client-1.8.3/keymaps/is
diff --git a/src/VBox/RDP/client/keymaps/it b/src/VBox/RDP/client-1.8.3/keymaps/it
similarity index 95%
rename from src/VBox/RDP/client/keymaps/it
rename to src/VBox/RDP/client-1.8.3/keymaps/it
index 00ca73a..3dfa24c 100644
--- a/src/VBox/RDP/client/keymaps/it
+++ b/src/VBox/RDP/client-1.8.3/keymaps/it
@@ -18,14 +18,12 @@ ampersand 0x07 shift
 threequarters 0x07 altgr
 fiveeighths 0x07 shift altgr
 slash 0x08 shift
-braceleft 0x08 altgr
 seveneighths 0x08 shift altgr
 parenleft 0x09 shift
 trademark 0x09 shift altgr
 parenright 0x0a shift
 plusminus 0x0a shift altgr
 equal 0x0b shift
-braceright 0x0b altgr
 degree 0x0b shift altgr
 apostrophe 0x0c
 question 0x0c shift
@@ -58,11 +56,11 @@ THORN 0x19 shift altgr
 egrave 0x1a
 eacute 0x1a shift
 bracketleft 0x1a altgr
-dead_abovering 0x1a shift altgr
+braceleft 0x1a shift altgr
 plus 0x1b
 asterisk 0x1b shift
 bracketright 0x1b altgr
-dead_macron 0x1b shift altgr
+braceright 0x1b shift altgr
 ae 0x1e altgr
 AE 0x1e shift altgr
 ssharp 0x1f altgr
diff --git a/src/VBox/RDP/client/keymaps/ja b/src/VBox/RDP/client-1.8.3/keymaps/ja
similarity index 100%
rename from src/VBox/RDP/client/keymaps/ja
rename to src/VBox/RDP/client-1.8.3/keymaps/ja
diff --git a/src/VBox/RDP/client/keymaps/ko b/src/VBox/RDP/client-1.8.3/keymaps/ko
similarity index 100%
rename from src/VBox/RDP/client/keymaps/ko
rename to src/VBox/RDP/client-1.8.3/keymaps/ko
diff --git a/src/VBox/RDP/client/keymaps/lt b/src/VBox/RDP/client-1.8.3/keymaps/lt
similarity index 100%
rename from src/VBox/RDP/client/keymaps/lt
rename to src/VBox/RDP/client-1.8.3/keymaps/lt
diff --git a/src/VBox/RDP/client/keymaps/lv b/src/VBox/RDP/client-1.8.3/keymaps/lv
similarity index 100%
rename from src/VBox/RDP/client/keymaps/lv
rename to src/VBox/RDP/client-1.8.3/keymaps/lv
diff --git a/src/VBox/RDP/client/keymaps/mk b/src/VBox/RDP/client-1.8.3/keymaps/mk
similarity index 100%
rename from src/VBox/RDP/client/keymaps/mk
rename to src/VBox/RDP/client-1.8.3/keymaps/mk
diff --git a/src/VBox/RDP/client/keymaps/modifiers b/src/VBox/RDP/client-1.8.3/keymaps/modifiers
similarity index 100%
rename from src/VBox/RDP/client/keymaps/modifiers
rename to src/VBox/RDP/client-1.8.3/keymaps/modifiers
diff --git a/src/VBox/RDP/client/keymaps/nl b/src/VBox/RDP/client-1.8.3/keymaps/nl
similarity index 98%
rename from src/VBox/RDP/client/keymaps/nl
rename to src/VBox/RDP/client-1.8.3/keymaps/nl
index bc823bd..089c6e5 100644
--- a/src/VBox/RDP/client/keymaps/nl
+++ b/src/VBox/RDP/client-1.8.3/keymaps/nl
@@ -52,7 +52,7 @@ semicolon 0x33 shift
 period 0x34
 colon 0x34 shift
 periodcentered 0x34 altgr
-hyphen 0x35
+minus 0x35
 equal 0x35 shift
 bracketright 0x56
 bracketleft 0x56 shift
diff --git a/src/VBox/RDP/client/keymaps/nl-be b/src/VBox/RDP/client-1.8.3/keymaps/nl-be
similarity index 100%
rename from src/VBox/RDP/client/keymaps/nl-be
rename to src/VBox/RDP/client-1.8.3/keymaps/nl-be
diff --git a/src/VBox/RDP/client/keymaps/no b/src/VBox/RDP/client-1.8.3/keymaps/no
similarity index 100%
rename from src/VBox/RDP/client/keymaps/no
rename to src/VBox/RDP/client-1.8.3/keymaps/no
diff --git a/src/VBox/RDP/client/keymaps/pl b/src/VBox/RDP/client-1.8.3/keymaps/pl
similarity index 100%
rename from src/VBox/RDP/client/keymaps/pl
rename to src/VBox/RDP/client-1.8.3/keymaps/pl
diff --git a/src/VBox/RDP/client/keymaps/pt b/src/VBox/RDP/client-1.8.3/keymaps/pt
similarity index 100%
rename from src/VBox/RDP/client/keymaps/pt
rename to src/VBox/RDP/client-1.8.3/keymaps/pt
diff --git a/src/VBox/RDP/client/keymaps/pt-br b/src/VBox/RDP/client-1.8.3/keymaps/pt-br
similarity index 100%
rename from src/VBox/RDP/client/keymaps/pt-br
rename to src/VBox/RDP/client-1.8.3/keymaps/pt-br
diff --git a/src/VBox/RDP/client/keymaps/ru b/src/VBox/RDP/client-1.8.3/keymaps/ru
similarity index 100%
rename from src/VBox/RDP/client/keymaps/ru
rename to src/VBox/RDP/client-1.8.3/keymaps/ru
diff --git a/src/VBox/RDP/client-1.8.3/keymaps/sk b/src/VBox/RDP/client-1.8.3/keymaps/sk
new file mode 100644
index 0000000..8c36c41
--- /dev/null
+++ b/src/VBox/RDP/client-1.8.3/keymaps/sk
@@ -0,0 +1,189 @@
+#Slovak keymap
+#2007-05-28 by Jaroslav Jiricka <giahra at atlas.cz>
+include common
+
+#Additional sequences
+#2007-05-28 by Jaroslav Jiricka <giahra at atlas.cz>
+
+sequence ecaron dead_caron e
+sequence Ecaron dead_caron E
+sequence eogonek dead_ogonek e
+sequence Eogonek dead_ogonek E
+
+sequence rcaron dead_caron r
+sequence Rcaron dead_caron R
+sequence racute dead_acute r
+sequence Racute dead_acute R
+
+sequence tcaron dead_caron t
+sequence Tcaron dead_caron T
+sequence tcedilla dead_cedilla t
+sequence Tcedilla dead_cedilla T
+
+sequence zcaron dead_caron z
+sequence Zcaron dead_caron Z
+sequence zacute dead_acute z
+sequence Zacute dead_acute Z
+sequence zabovedot dead_abovedot z
+sequence Zabovedot dead_abovedot Z
+
+sequence uring dead_abovering u
+sequence Uring dead_abovering U
+sequence udoubleacute dead_doubleacute u
+sequence Udoubleacute dead_doubleacute U
+
+sequence odoubleacute dead_doubleacute o
+sequence Odoubleacute dead_doubleacute O
+
+sequence aogonek dead_ogonek a
+sequence Aogonek dead_ogonek A
+sequence abreve dead_breve a
+sequence Abreve dead_breve A
+
+sequence scaron dead_caron s
+sequence Scaron dead_caron S
+sequence sacute dead_acute s
+sequence Sacute dead_acute S
+sequence scedilla dead_cedilla s
+sequence Scedilla dead_cedilla S
+
+sequence dcaron dead_caron d
+sequence Dcaron dead_caron D
+
+sequence gbreve dead_breve g
+sequence Gbreve dead_breve G
+
+sequence lcaron dead_caron l
+sequence Lcaron dead_caron L
+sequence lacute dead_acute l
+sequence Lacute dead_acute L
+
+sequence ccaron dead_caron c
+sequence Ccaron dead_caron C
+
+sequence ncaron dead_caron n
+sequence Ncaron dead_caron N
+sequence nacute dead_acute n
+sequence Nacute dead_acute N
+#Additional sequences end
+
+map 0x41B
+
+semicolon 0x29
+dead_abovering 0x29 shift
+
+plus 0x02
+1 0x02 shift
+dead_tilde 0x02 altgr
+asciitilde 0x02 altgr
+
+lcaron 0x03
+2 0x03 shift
+dead_caron 0x03 altgr
+
+scaron 0x04
+3 0x04 shift
+dead_circumflex 0x04 altgr
+
+ccaron 0x05
+4 0x05 shift
+dead_breve 0x05 altgr
+
+tcaron 0x06
+5 0x06 shift
+dead_abovering 0x06 altgr
+
+zcaron 0x07
+6 0x07 shift
+dead_ogonek 0x07 altgr
+
+yacute 0x08
+7 0x08 shift
+dead_grave 0x08 altgr
+
+aacute 0x09
+8 0x09 shift
+dead_abovedot 0x08 altgr
+
+iacute 0x0a
+9 0x0a shift
+dead_acute 0x08 altgr
+
+eacute 0x0b
+0 0x0b shift
+dead_doubleacute 0x0b altgr
+
+equal 0x0c
+percent 0x0c shift
+dead_diaeresis 0x0c altgr
+
+dead_acute 0x0d
+dead_caron 0x0d shift
+dead_cedilla 0x0d altgr
+
+backslash 0x10 altgr
+
+bar 0x11 altgr
+
+EuroSign 0x12 altgr
+
+z 0x15 addupper
+
+apostrophe 0x19 altgr
+
+uacute 0x1a
+slash 0x1a shift
+division 0x1a altgr
+
+adiaeresis 0x1b
+parenleft 0x1b shift
+multiply 0x1b altgr
+
+ncaron 0x2b
+parenright 0x2b shift
+currency 0x2b altgr
+
+dstroke 0x1f altgr
+
+Dstroke 0x20 altgr
+
+bracketleft 0x21 altgr
+
+bracketright 0x22 altgr
+
+lstroke 0x25 altgr
+
+Lstroke 0x26 altgr
+
+ocircumflex 0x27
+quotedbl 0x27 shift
+dollar 0x27 altgr
+
+section 0x28
+exclam 0x28 shift
+ssharp 0x28 altgr
+
+y 0x2c addupper
+
+numbersign 0x2d altgr
+
+ampersand 0x2e altgr
+
+at 0x2f altgr
+
+braceleft 0x30 altgr
+
+braceright 0x31 altgr
+
+comma 0x33
+question 0x33 shift
+less 0x33 altgr
+
+period 0x34
+colon 0x34 shift
+greater 0x34 altgr
+
+minus 0x35
+underscore 0x35 shift
+asterisk 0x35 altgr
+
diff --git a/src/VBox/RDP/client/keymaps/sl b/src/VBox/RDP/client-1.8.3/keymaps/sl
similarity index 100%
rename from src/VBox/RDP/client/keymaps/sl
rename to src/VBox/RDP/client-1.8.3/keymaps/sl
diff --git a/src/VBox/RDP/client/keymaps/sv b/src/VBox/RDP/client-1.8.3/keymaps/sv
similarity index 100%
rename from src/VBox/RDP/client/keymaps/sv
rename to src/VBox/RDP/client-1.8.3/keymaps/sv
diff --git a/src/VBox/RDP/client/keymaps/th b/src/VBox/RDP/client-1.8.3/keymaps/th
similarity index 100%
rename from src/VBox/RDP/client/keymaps/th
rename to src/VBox/RDP/client-1.8.3/keymaps/th
diff --git a/src/VBox/RDP/client/keymaps/tr b/src/VBox/RDP/client-1.8.3/keymaps/tr
similarity index 100%
rename from src/VBox/RDP/client/keymaps/tr
rename to src/VBox/RDP/client-1.8.3/keymaps/tr
diff --git a/src/VBox/RDP/client/licence.c b/src/VBox/RDP/client-1.8.3/licence.c
similarity index 57%
rename from src/VBox/RDP/client/licence.c
rename to src/VBox/RDP/client-1.8.3/licence.c
index 12c6406..1763a9b 100644
--- a/src/VBox/RDP/client/licence.c
+++ b/src/VBox/RDP/client-1.8.3/licence.c
@@ -2,6 +2,9 @@
    rdesktop: A Remote Desktop Protocol client.
    RDP licensing negotiation
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
+   Copyright (C) Thomas Uhle <thomas.uhle at mailbox.tu-dresden.de> 2011
+   Copyright (C) Henrik Andersson <henrik.andersson at cendio.com> 2014
+
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -31,11 +34,13 @@
 
 extern char *g_username;
 extern char g_hostname[16];
+extern RDP_VERSION g_rdp_version;
 
 static uint8 g_licence_key[16];
 static uint8 g_licence_sign_key[16];
 
 RD_BOOL g_licence_issued = False;
+RD_BOOL g_licence_error_result = False;
 
 /* Generate a session key and RC4 keys, given client and server randoms */
 static void
@@ -62,21 +67,21 @@ licence_generate_hwid(uint8 * hwid)
 	strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4);
 }
 
-/* Present an existing licence to the server */
+/* Send a lincece info packet to server */
 static void
-licence_present(uint8 * client_random, uint8 * rsa_data,
-		uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
+licence_info(uint8 * client_random, uint8 * rsa_data,
+	     uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
 {
 	uint32 sec_flags = SEC_LICENCE_NEG;
 	uint16 length =
-		16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
+		24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
 		licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
 	STREAM s;
 
-	s = sec_init(sec_flags, length + 4);
+	s = sec_init(sec_flags, length + 2);
 
-	out_uint8(s, LICENCE_TAG_PRESENT);
-	out_uint8(s, 2);	/* version */
+	out_uint8(s, LICENCE_TAG_LICENCE_INFO);
+	out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2));	/* version */
 	out_uint16_le(s, length);
 
 	out_uint32_le(s, 1);
@@ -84,7 +89,7 @@ licence_present(uint8 * client_random, uint8 * rsa_data,
 	out_uint16_le(s, 0x0201);
 
 	out_uint8p(s, client_random, SEC_RANDOM_SIZE);
-	out_uint16(s, 0);
+	out_uint16_le(s, 2);
 	out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
 	out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
 	out_uint8s(s, SEC_PADDING_SIZE);
@@ -103,37 +108,40 @@ licence_present(uint8 * client_random, uint8 * rsa_data,
 	sec_send(s, sec_flags);
 }
 
-/* Send a licence request packet */
+/* Send a new licence request packet */
 static void
-licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
+licence_send_new_licence_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
 {
 	uint32 sec_flags = SEC_LICENCE_NEG;
 	uint16 userlen = strlen(user) + 1;
 	uint16 hostlen = strlen(host) + 1;
-	uint16 length = 128 + userlen + hostlen;
+	uint16 length =
+		24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + userlen + hostlen;
 	STREAM s;
 
 	s = sec_init(sec_flags, length + 2);
 
-	out_uint8(s, LICENCE_TAG_REQUEST);
-	out_uint8(s, 2);	/* version */
+	out_uint8(s, LICENCE_TAG_NEW_LICENCE_REQUEST);
+	out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2));	/* version */
 	out_uint16_le(s, length);
 
-	out_uint32_le(s, 1);
+	out_uint32_le(s, 1);	// KEY_EXCHANGE_ALG_RSA
 	out_uint16(s, 0);
 	out_uint16_le(s, 0xff01);
 
 	out_uint8p(s, client_random, SEC_RANDOM_SIZE);
-	out_uint16(s, 0);
+	out_uint16_le(s, 2);
 	out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
 	out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
 	out_uint8s(s, SEC_PADDING_SIZE);
 
-	out_uint16_le(s, LICENCE_TAG_USER);
+	/* Username LICENSE_BINARY_BLOB */
+	out_uint16_le(s, BB_CLIENT_USER_NAME_BLOB);
 	out_uint16_le(s, userlen);
 	out_uint8p(s, user, userlen);
 
-	out_uint16_le(s, LICENCE_TAG_HOST);
+	/* Machinename LICENSE_BINARY_BLOB */
+	out_uint16_le(s, BB_CLIENT_MACHINE_NAME_BLOB);
 	out_uint16_le(s, hostlen);
 	out_uint8p(s, host, hostlen);
 
@@ -141,9 +149,9 @@ licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *
 	sec_send(s, sec_flags);
 }
 
-/* Process a licence demand packet */
+/* Process a licence request packet */
 static void
-licence_process_demand(STREAM s)
+licence_process_request(STREAM s)
 {
 	uint8 null_data[SEC_MODULUS_SIZE];
 	uint8 *server_random;
@@ -151,7 +159,7 @@ licence_process_demand(STREAM s)
 	uint8 hwid[LICENCE_HWID_SIZE];
 	uint8 *licence_data;
 	int licence_size;
-	SSL_RC4 crypt_key;
+	RDSSL_RC4 crypt_key;
 
 	/* Retrieve the server random from the incoming packet */
 	in_uint8p(s, server_random, SEC_RANDOM_SIZE);
@@ -169,20 +177,27 @@ licence_process_demand(STREAM s)
 		sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid));
 
 		/* Now encrypt the HWID */
-		ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
-		ssl_rc4_crypt(&crypt_key, hwid, hwid, sizeof(hwid));
+		rdssl_rc4_set_key(&crypt_key, g_licence_key, 16);
+		rdssl_rc4_crypt(&crypt_key, hwid, hwid, sizeof(hwid));
+
+#if WITH_DEBUG
+		DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_LICENCE_INFO));
+#endif
+		licence_info(null_data, null_data, licence_data, licence_size, hwid, signature);
 
-		licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
 		xfree(licence_data);
 		return;
 	}
 
-	licence_send_request(null_data, null_data, g_username, g_hostname);
+#if WITH_DEBUG
+	DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_NEW_LICENCE_REQUEST));
+#endif
+	licence_send_new_licence_request(null_data, null_data, g_username, g_hostname);
 }
 
-/* Send an authentication response packet */
+/* Send a platform challange response packet */
 static void
-licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
+licence_send_platform_challange_response(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
 {
 	uint32 sec_flags = SEC_LICENCE_NEG;
 	uint16 length = 58;
@@ -190,8 +205,8 @@ licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
 
 	s = sec_init(sec_flags, length + 2);
 
-	out_uint8(s, LICENCE_TAG_AUTHRESP);
-	out_uint8(s, 2);	/* version */
+	out_uint8(s, LICENCE_TAG_PLATFORM_CHALLANGE_RESPONSE);
+	out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2));	/* version */
 	out_uint16_le(s, length);
 
 	out_uint16_le(s, 1);
@@ -208,9 +223,9 @@ licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
 	sec_send(s, sec_flags);
 }
 
-/* Parse an authentication request packet */
+/* Parse an platform challange request packet */
 static RD_BOOL
-licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
+licence_parse_platform_challange(STREAM s, uint8 ** token, uint8 ** signature)
 {
 	uint16 tokenlen;
 
@@ -229,24 +244,24 @@ licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
 	return s_check_end(s);
 }
 
-/* Process an authentication request packet */
+/* Process a platform challange  packet */
 static void
-licence_process_authreq(STREAM s)
+licence_process_platform_challange(STREAM s)
 {
 	uint8 *in_token = NULL, *in_sig;
 	uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
 	uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];
 	uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
 	uint8 out_sig[LICENCE_SIGNATURE_SIZE];
-	SSL_RC4 crypt_key;
+	RDSSL_RC4 crypt_key;
 
 	/* Parse incoming packet and save the encrypted token */
-	licence_parse_authreq(s, &in_token, &in_sig);
+	licence_parse_platform_challange(s, &in_token, &in_sig);
 	memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);
 
 	/* Decrypt the token. It should read TEST in Unicode. */
-	ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
-	ssl_rc4_crypt(&crypt_key, in_token, decrypt_token, LICENCE_TOKEN_SIZE);
+	rdssl_rc4_set_key(&crypt_key, g_licence_key, 16);
+	rdssl_rc4_crypt(&crypt_key, in_token, decrypt_token, LICENCE_TOKEN_SIZE);
 
 	/* Generate a signature for a buffer of token and HWID */
 	licence_generate_hwid(hwid);
@@ -255,38 +270,33 @@ licence_process_authreq(STREAM s)
 	sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));
 
 	/* Now encrypt the HWID */
-	ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
-	ssl_rc4_crypt(&crypt_key, hwid, crypt_hwid, LICENCE_HWID_SIZE);
+	rdssl_rc4_set_key(&crypt_key, g_licence_key, 16);
+	rdssl_rc4_crypt(&crypt_key, hwid, crypt_hwid, LICENCE_HWID_SIZE);
 
-	licence_send_authresp(out_token, crypt_hwid, out_sig);
+	licence_send_platform_challange_response(out_token, crypt_hwid, out_sig);
 }
 
-/* Process an licence issue packet */
+/* Process a new licence packet */
 static void
-licence_process_issue(STREAM s)
+licence_process_new_license(STREAM s)
 {
-	SSL_RC4 crypt_key;
+	RDSSL_RC4 crypt_key;
 	uint32 length;
-	uint16 check;
 	int i;
 
-	in_uint8s(s, 2);	/* 3d 45 - unknown */
+	in_uint8s(s, 2);	// Skip license binary blob type
 	in_uint16_le(s, length);
 	if (!s_check_rem(s, length))
 		return;
 
-	ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
-	ssl_rc4_crypt(&crypt_key, s->p, s->p, length);
+	rdssl_rc4_set_key(&crypt_key, g_licence_key, 16);
+	rdssl_rc4_crypt(&crypt_key, s->p, s->p, length);
 
-	in_uint16(s, check);
-	if (check != 0)
-		return;
+	/* Parse NEW_LICENSE_INFO block */
+	in_uint8s(s, 4);	// skip dwVersion
 
-	g_licence_issued = True;
-
-	in_uint8s(s, 2);	/* pad */
-
-	/* advance to fourth string */
+	/* Skip strings, Scope, CompanyName and ProductId to get
+	   to the LicenseInfo which we store in license blob. */
 	length = 0;
 	for (i = 0; i < 4; i++)
 	{
@@ -300,6 +310,53 @@ licence_process_issue(STREAM s)
 	save_licence(s->p, length);
 }
 
+/* process a licence error alert packet */
+void
+licence_process_error_alert(STREAM s)
+{
+	uint32 error_code;
+	uint32 state_transition;
+	uint32 error_info;
+	in_uint32(s, error_code);
+	in_uint32(s, state_transition);
+	in_uint32(s, error_info);
+
+	/* There is a special case in the error alert handling, when licensing is all good
+	   and the server is not sending a license to client, a "Server License Error PDU -
+	   Valid Client" packet is sent which means, every thing is ok.
+
+	   Therefor we should flag that everything is ok with license here.
+	 */
+	if (error_code == 0x07)
+	{
+		g_licence_issued = True;
+		return;
+	}
+
+	/* handle error codes, for now, jsut report them */
+	switch (error_code)
+	{
+		case 0x6:	// ERR_NO_LICENSE_SERVER
+			warning("License error alert from server: No license server\n");
+			break;
+
+		case 0x8:	// ERR_INVALID_CLIENT
+			warning("License error alert from server: Invalid client\n");
+			break;
+
+		case 0x4:	// ERR_INVALID_SCOPE
+		case 0xb:	// ERR_INVALID_PRODUCTID
+		case 0xc:	// ERR_INVALID_MESSAGE_LENGTH
+		default:
+			warning("License error alert from server: code %u, state transition %u\n",
+				error_code, state_transition);
+			break;
+	}
+
+	g_licence_error_result = True;
+}
+
+
 /* Process a licence packet */
 void
 licence_process(STREAM s)
@@ -309,25 +366,31 @@ licence_process(STREAM s)
 	in_uint8(s, tag);
 	in_uint8s(s, 3);	/* version, length */
 
+#if WITH_DEBUG
+	DEBUG(("Received licensing PDU (message type 0x%02x)\n", tag));
+#endif
+
 	switch (tag)
 	{
-		case LICENCE_TAG_DEMAND:
-			licence_process_demand(s);
+		case LICENCE_TAG_REQUEST:
+			licence_process_request(s);
 			break;
 
-		case LICENCE_TAG_AUTHREQ:
-			licence_process_authreq(s);
+		case LICENCE_TAG_PLATFORM_CHALLANGE:
+			licence_process_platform_challange(s);
 			break;
 
-		case LICENCE_TAG_ISSUE:
-			licence_process_issue(s);
+		case LICENCE_TAG_NEW_LICENCE:
+		case LICENCE_TAG_UPGRADE_LICENCE:
+			/* we can handle new and upgrades of licences the same way. */
+			licence_process_new_license(s);
 			break;
 
-		case LICENCE_TAG_REISSUE:
-		case LICENCE_TAG_RESULT:
+		case LICENCE_TAG_ERROR_ALERT:
+			licence_process_error_alert(s);
 			break;
 
 		default:
-			unimpl("licence tag 0x%x\n", tag);
+			unimpl("licence tag 0x%02x\n", tag);
 	}
 }
diff --git a/src/VBox/RDP/client/lspci.c b/src/VBox/RDP/client-1.8.3/lspci.c
similarity index 100%
rename from src/VBox/RDP/client/lspci.c
rename to src/VBox/RDP/client-1.8.3/lspci.c
diff --git a/src/VBox/RDP/client/mcs.c b/src/VBox/RDP/client-1.8.3/mcs.c
similarity index 88%
rename from src/VBox/RDP/client/mcs.c
rename to src/VBox/RDP/client-1.8.3/mcs.c
index 0a104de..c378091 100644
--- a/src/VBox/RDP/client/mcs.c
+++ b/src/VBox/RDP/client-1.8.3/mcs.c
@@ -33,71 +33,6 @@ uint16 g_mcs_userid;
 extern VCHANNEL g_channels[];
 extern unsigned int g_num_channels;
 
-/* Parse an ASN.1 BER header */
-static RD_BOOL
-ber_parse_header(STREAM s, int tagval, int *length)
-{
-	int tag, len;
-
-	if (tagval > 0xff)
-	{
-		in_uint16_be(s, tag);
-	}
-	else
-	{
-		in_uint8(s, tag);
-	}
-
-	if (tag != tagval)
-	{
-		error("expected tag %d, got %d\n", tagval, tag);
-		return False;
-	}
-
-	in_uint8(s, len);
-
-	if (len & 0x80)
-	{
-		len &= ~0x80;
-		*length = 0;
-		while (len--)
-			next_be(s, *length);
-	}
-	else
-		*length = len;
-
-	return s_check(s);
-}
-
-/* Output an ASN.1 BER header */
-static void
-ber_out_header(STREAM s, int tagval, int length)
-{
-	if (tagval > 0xff)
-	{
-		out_uint16_be(s, tagval);
-	}
-	else
-	{
-		out_uint8(s, tagval);
-	}
-
-	if (length >= 0x80)
-	{
-		out_uint8(s, 0x82);
-		out_uint16_be(s, length);
-	}
-	else
-		out_uint8(s, length);
-}
-
-/* Output an ASN.1 BER integer */
-static void
-ber_out_integer(STREAM s, int value)
-{
-	ber_out_header(s, BER_TAG_INTEGER, 2);
-	out_uint16_be(s, value);
-}
 
 /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
 static void
@@ -382,12 +317,16 @@ mcs_recv(uint16 * channel, uint8 * rdpver)
 }
 
 RD_BOOL
-mcs_connect(char *server, STREAM mcs_data, char *username, RD_BOOL reconnect)
+mcs_connect_start(char *server, char *username, char *domain, char *password,
+		  RD_BOOL reconnect, uint32 * selected_protocol)
 {
-	unsigned int i;
+	return iso_connect(server, username, domain, password, reconnect, selected_protocol);
+}
 
-	if (!iso_connect(server, username, reconnect))
-		return False;
+RD_BOOL
+mcs_connect_finalize(STREAM mcs_data)
+{
+	unsigned int i;
 
 	mcs_send_connect_initial(mcs_data);
 	if (!mcs_recv_connect_response(mcs_data))
diff --git a/src/VBox/RDP/client/mppc.c b/src/VBox/RDP/client-1.8.3/mppc.c
similarity index 100%
rename from src/VBox/RDP/client/mppc.c
rename to src/VBox/RDP/client-1.8.3/mppc.c
diff --git a/src/VBox/RDP/client/orders.c b/src/VBox/RDP/client-1.8.3/orders.c
similarity index 99%
rename from src/VBox/RDP/client/orders.c
rename to src/VBox/RDP/client-1.8.3/orders.c
index 3d71502..871a6e5 100644
--- a/src/VBox/RDP/client/orders.c
+++ b/src/VBox/RDP/client-1.8.3/orders.c
@@ -31,7 +31,7 @@
 
 extern uint8 *g_next_packet;
 static RDP_ORDER_STATE g_order_state;
-extern RD_BOOL g_use_rdp5;
+extern RDP_VERSION g_rdp_version;
 
 /* Read field indicating which parameters are present */
 static void
@@ -977,7 +977,7 @@ process_bmpcache(STREAM s)
 	in_uint16_le(s, bufsize);	/* bufsize */
 	in_uint16_le(s, cache_idx);
 
-	if (g_use_rdp5)
+	if (g_rdp_version >= RDP_V5)
 	{
 		size = bufsize;
 	}
diff --git a/src/VBox/RDP/client/orders.h b/src/VBox/RDP/client-1.8.3/orders.h
similarity index 100%
rename from src/VBox/RDP/client/orders.h
rename to src/VBox/RDP/client-1.8.3/orders.h
diff --git a/src/VBox/RDP/client/parallel.c b/src/VBox/RDP/client-1.8.3/parallel.c
similarity index 100%
rename from src/VBox/RDP/client/parallel.c
rename to src/VBox/RDP/client-1.8.3/parallel.c
diff --git a/src/VBox/RDP/client/parse.h b/src/VBox/RDP/client-1.8.3/parse.h
similarity index 96%
rename from src/VBox/RDP/client/parse.h
rename to src/VBox/RDP/client-1.8.3/parse.h
index a4b690d..373cb51 100644
--- a/src/VBox/RDP/client/parse.h
+++ b/src/VBox/RDP/client-1.8.3/parse.h
@@ -2,6 +2,7 @@
    rdesktop: A Remote Desktop Protocol client.
    Parsing primitives
    Copyright (C) Matthew Chapman 1999-2008
+   Copyright 2012 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -50,6 +51,8 @@ typedef struct stream
 #define s_check(s)		((s)->p <= (s)->end)
 #define s_check_rem(s,n)	((s)->p + n <= (s)->end)
 #define s_check_end(s)		((s)->p == (s)->end)
+#define s_length(s)		((s)->end - (s)->data)
+#define s_reset(s)		((s)->end = (s)->p = (s)->data)
 
 #if defined(L_ENDIAN) && !defined(NEED_ALIGN)
 #define in_uint16_le(s,v)	{ v = *(uint16 *)((s)->p); (s)->p += 2; }
diff --git a/src/VBox/RDP/client/printer.c b/src/VBox/RDP/client-1.8.3/printer.c
similarity index 97%
rename from src/VBox/RDP/client/printer.c
rename to src/VBox/RDP/client-1.8.3/printer.c
index 115a095..c11b331 100644
--- a/src/VBox/RDP/client/printer.c
+++ b/src/VBox/RDP/client-1.8.3/printer.c
@@ -89,7 +89,7 @@ printer_enum_devices(uint32 * id, char *optarg)
 		}
 
 		if (!pos2 || (*pos2 == (char) 0x00))
-			pprinter_data->driver = "HP Color LaserJet 8500 PS";	/* no printer driver supplied set default */
+			pprinter_data->driver = "MS Publisher Imagesetter";	/* no printer driver supplied set default */
 		else
 		{
 			pprinter_data->driver = xmalloc(strlen(pos2) + 1);
diff --git a/src/VBox/RDP/client/printercache.c b/src/VBox/RDP/client-1.8.3/printercache.c
similarity index 90%
rename from src/VBox/RDP/client/printercache.c
rename to src/VBox/RDP/client-1.8.3/printercache.c
index 500a21c..14ed6ac 100644
--- a/src/VBox/RDP/client/printercache.c
+++ b/src/VBox/RDP/client-1.8.3/printercache.c
@@ -3,6 +3,8 @@
    Entrypoint and utility functions
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
    Copyright (C) Jeroen Meijer <jeroen at oldambt7.com> 2003-2008
+   Copyright (C) Henrik Andersson <hean01 at cendio.com> 2013
+   
   
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -240,7 +242,9 @@ void
 printercache_process(STREAM s)
 {
 	uint32 type, printer_length, driver_length, printer_unicode_length, blob_length;
-	char device_name[9], printer[256], driver[256];
+	char device_name[9], *printer, *driver;
+
+	printer = driver = NULL;
 
 	in_uint32_le(s, type);
 	switch (type)
@@ -253,17 +257,23 @@ printercache_process(STREAM s)
 
 			/* NOTE - 'driver' doesn't contain driver, it contains the new printer name */
 
-			rdp_in_unistr(s, printer, sizeof(printer), printer_length);
-			rdp_in_unistr(s, driver, sizeof(driver), driver_length);
+			rdp_in_unistr(s, printer_length, &printer, &printer_length);
+			rdp_in_unistr(s, driver_length, &driver, &driver_length);
+
+			if (printer != NULL && driver != NULL)
+				printercache_rename_blob(printer, driver);
 
-			printercache_rename_blob(printer, driver);
+			free(printer);
+			free(driver);
 			break;
 
 		case 3:	/* delete item */
 			in_uint8(s, printer_unicode_length);
 			in_uint8s(s, 0x3);	/* padding */
-			rdp_in_unistr(s, printer, sizeof(printer), printer_unicode_length);
-			printercache_unlink_blob(printer);
+			rdp_in_unistr(s, printer_unicode_length, &printer, &printer_unicode_length);
+			if (printer)
+				printercache_unlink_blob(printer);
+			free(printer);
 			break;
 
 		case 2:	/* save printer data */
@@ -272,8 +282,11 @@ printercache_process(STREAM s)
 
 			if (printer_unicode_length < 2 * 255)
 			{
-				rdp_in_unistr(s, printer, sizeof(printer), printer_unicode_length);
-				printercache_save_blob(printer, s->p, blob_length);
+				rdp_in_unistr(s, printer_unicode_length, &printer,
+					      &printer_unicode_length);
+				if (printer)
+					printercache_save_blob(printer, s->p, blob_length);
+				free(printer);
 			}
 			break;
 
diff --git a/src/VBox/RDP/client/proto.h b/src/VBox/RDP/client-1.8.3/proto.h
similarity index 88%
rename from src/VBox/RDP/client/proto.h
rename to src/VBox/RDP/client-1.8.3/proto.h
index c178068..69cd2f4 100644
--- a/src/VBox/RDP/client/proto.h
+++ b/src/VBox/RDP/client-1.8.3/proto.h
@@ -33,6 +33,12 @@
 extern "C" {
 #endif
 /* *INDENT-ON* */
+/* utils.c */
+char *utils_string_escape(const char *str);
+char *utils_string_unescape(const char *str);
+int utils_locale_to_utf8(const char *src, size_t is, char *dest, size_t os);
+int utils_mkdir_safe(const char *path, int mask);
+int utils_mkdir_p(const char *path, int mask);
 /* bitmap.c */
 RD_BOOL bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp);
 /* cache.c */
@@ -66,6 +72,14 @@ void cliprdr_send_data_request(uint32 format);
 void cliprdr_send_data(uint8 * data, uint32 length);
 void cliprdr_set_mode(const char *optarg);
 RD_BOOL cliprdr_init(void);
+/* ctrl.c */
+int ctrl_init(const char *user, const char *domain, const char *host);
+void ctrl_cleanup();
+RD_BOOL ctrl_is_slave();
+int ctrl_send_command(const char *cmd, const char *args);
+void ctrl_add_fds(int *n, fd_set * rfds);
+void ctrl_check_fds(fd_set * rfds, fd_set * wfds);
+
 /* disk.c */
 int disk_enum_devices(uint32 * id, char *optarg);
 RD_NTSTATUS disk_query_information(RD_NTHANDLE handle, uint32 info_class, STREAM out);
@@ -83,9 +97,12 @@ void ewmh_init(void);
 STREAM iso_init(int length);
 void iso_send(STREAM s);
 STREAM iso_recv(uint8 * rdpver);
-RD_BOOL iso_connect(char *server, char *username, RD_BOOL reconnect);
+RD_BOOL iso_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect,
+		    uint32 * selected_protocol);
 void iso_disconnect(void);
 void iso_reset_state(void);
+/* cssp.c */
+RD_BOOL cssp_connect(char *server, char *user, char *domain, char *password, STREAM s);
 /* licence.c */
 void licence_process(STREAM s);
 /* mcs.c */
@@ -93,7 +110,9 @@ STREAM mcs_init(int length);
 void mcs_send_to_channel(STREAM s, uint16 channel);
 void mcs_send(STREAM s);
 STREAM mcs_recv(uint16 * channel, uint8 * rdpver);
-RD_BOOL mcs_connect(char *server, STREAM mcs_data, char *username, RD_BOOL reconnect);
+RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password,
+			  RD_BOOL reconnect, uint32 * selected_protocol);
+RD_BOOL mcs_connect_finalize(STREAM s);
 void mcs_disconnect(void);
 void mcs_reset_state(void);
 /* orders.c */
@@ -134,6 +153,7 @@ RD_BOOL subprocess(char *const argv[], str_handle_lines_t linehandler, void *dat
 char *l_to_a(long N, int base);
 int load_licence(unsigned char **data);
 void save_licence(unsigned char *data, int length);
+void rd_create_ui(void);
 RD_BOOL rd_pstcache_mkdir(void);
 int rd_open_file(char *filename);
 void rd_close_file(int fd);
@@ -145,7 +165,7 @@ RD_BOOL rd_lock_file(int fd, int start, int len);
 void rdp5_process(STREAM s);
 /* rdp.c */
 void rdp_out_unistr(STREAM s, char *string, int len);
-int rdp_in_unistr(STREAM s, char *string, int str_len, int in_len);
+void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size);
 void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
 		    uint16 param2);
 void rdp_send_client_window_status(int status);
@@ -185,6 +205,8 @@ void rdpsnd_queue_next(unsigned long completed_in_us);
 int rdpsnd_queue_next_tick(void);
 void rdpsnd_reset_state(void);
 /* secure.c */
+void sec_hash_to_string(char *out, int out_size, uint8 * in, int in_size);
+void sec_hash_sha1_16(uint8 * out, uint8 * in, uint8 * salt1);
 void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
 void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);
 void buf_out_uint32(uint8 * buffer, uint32 value);
@@ -196,7 +218,7 @@ void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel);
 void sec_send(STREAM s, uint32 flags);
 void sec_process_mcs_data(STREAM s);
 STREAM sec_recv(uint8 * rdpver);
-RD_BOOL sec_connect(char *server, char *username, RD_BOOL reconnect);
+RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect);
 void sec_disconnect(void);
 void sec_reset_state(void);
 /* serial.c */
@@ -211,7 +233,18 @@ STREAM tcp_recv(STREAM s, uint32 length);
 RD_BOOL tcp_connect(char *server);
 void tcp_disconnect(void);
 char *tcp_get_address(void);
+RD_BOOL tcp_is_connected(void);
 void tcp_reset_state(void);
+RD_BOOL tcp_tls_connect(void);
+RD_BOOL tcp_tls_get_server_pubkey(STREAM s);
+void tcp_run_ui(RD_BOOL run);
+
+/* asn.c */
+RD_BOOL ber_in_header(STREAM s, int *tagval, int *length);
+void ber_out_header(STREAM s, int tagval, int length);
+RD_BOOL ber_parse_header(STREAM s, int tagval, int *length);
+void ber_out_integer(STREAM s, int value);
+
 /* xclip.c */
 void ui_clip_format_announce(uint8 * data, uint32 length);
 void ui_clip_handle_data(uint8 * data, uint32 length);
@@ -246,6 +279,7 @@ void ui_deinit(void);
 RD_BOOL ui_create_window(void);
 void ui_resize_window(void);
 void ui_destroy_window(void);
+RD_BOOL ui_have_window(void);
 void xwin_toggle_fullscreen(void);
 int ui_select(int rdp_socket);
 void ui_move_pointer(int x, int y);
@@ -311,6 +345,7 @@ void ui_seamless_ack(unsigned int serial);
 RD_BOOL lspci_init(void);
 /* seamless.c */
 RD_BOOL seamless_init(void);
+void seamless_reset_state(void);
 unsigned int seamless_send_sync(void);
 unsigned int seamless_send_state(unsigned long id, unsigned int state, unsigned long flags);
 unsigned int seamless_send_position(unsigned long id, int x, int y, int width, int height,
@@ -319,11 +354,14 @@ void seamless_select_timeout(struct timeval *tv);
 unsigned int seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags);
 unsigned int seamless_send_focus(unsigned long id, unsigned long flags);
 unsigned int seamless_send_destroy(unsigned long id);
+unsigned int seamless_send_spawn(char *cmd);
+unsigned int seamless_send_persistent(RD_BOOL);
+
 /* scard.c */
 void scard_lock(int lock);
 void scard_unlock(int lock);
 int scard_enum_devices(uint32 * id, char *optarg);
-void scardSetInfo(uint32 device, uint32 id, uint32 bytes_out);
+void scardSetInfo(uint32 epoch, uint32 device, uint32 id, uint32 bytes_out);
 void scard_reset_state();
 /* vrdp/rdpusb.c */
 RD_BOOL rdpusb_init(void);
diff --git a/src/VBox/RDP/client/proto.head b/src/VBox/RDP/client-1.8.3/proto.head
similarity index 100%
rename from src/VBox/RDP/client/proto.head
rename to src/VBox/RDP/client-1.8.3/proto.head
diff --git a/src/VBox/RDP/client/proto.tail b/src/VBox/RDP/client-1.8.3/proto.tail
similarity index 100%
rename from src/VBox/RDP/client/proto.tail
rename to src/VBox/RDP/client-1.8.3/proto.tail
diff --git a/src/VBox/RDP/client/pstcache.c b/src/VBox/RDP/client-1.8.3/pstcache.c
similarity index 100%
rename from src/VBox/RDP/client/pstcache.c
rename to src/VBox/RDP/client-1.8.3/pstcache.c
diff --git a/src/VBox/RDP/client/rdesktop.c b/src/VBox/RDP/client-1.8.3/rdesktop.c
similarity index 79%
rename from src/VBox/RDP/client/rdesktop.c
rename to src/VBox/RDP/client-1.8.3/rdesktop.c
index e126971..27300f5 100644
--- a/src/VBox/RDP/client/rdesktop.c
+++ b/src/VBox/RDP/client-1.8.3/rdesktop.c
@@ -3,7 +3,7 @@
    Entrypoint and utility functions
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
    Copyright 2002-2011 Peter Astrand <astrand at cendio.se> for Cendio AB
-   Copyright 2010-2011 Henrik Andersson <hean01 at cendio.se> for Cendio AB
+   Copyright 2010-2014 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -37,6 +37,7 @@
 #include <sys/time.h>		/* gettimeofday */
 #include <sys/times.h>		/* times */
 #include <ctype.h>		/* toupper */
+#include <limits.h>
 #include <errno.h>
 #include <signal.h>
 #include "rdesktop.h"
@@ -63,9 +64,19 @@
 
 #include "ssl.h"
 
+/* Reconnect timeout based on approxiamted cookie life-time */
+#define RECONNECT_TIMEOUT (3600+600)
+#define RDESKTOP_LICENSE_STORE "/.local/share/rdesktop/licenses"
+
+uint8 g_static_rdesktop_salt_16[16] = {
+	0xb8, 0x82, 0x29, 0x31, 0xc5, 0x39, 0xd9, 0x44,
+	0x54, 0x15, 0x5e, 0x14, 0x71, 0x38, 0xd5, 0x4d
+};
+
 char g_title[64] = "";
 char *g_username;
-char g_hostname[16];
+char g_password[64] = "";
+char g_hostname[16] = "";
 char g_keymapname[PATH_MAX] = "";
 unsigned int g_keylayout = 0x409;	/* Defaults to US keyboard layout */
 int g_keyboard_type = 0x4;	/* Defaults to US keyboard layout */
@@ -86,19 +97,22 @@ int g_pos = 0;			/* 0 position unspecified,
 extern int g_tcp_port_rdp;
 int g_server_depth = -1;
 int g_win_button_size = 0;	/* If zero, disable single app mode */
+RD_BOOL g_network_error = False;
 RD_BOOL g_bitmap_compression = True;
 RD_BOOL g_sendmotion = True;
 RD_BOOL g_bitmap_cache = True;
 RD_BOOL g_bitmap_cache_persist_enable = False;
 RD_BOOL g_bitmap_cache_precache = True;
+RD_BOOL g_use_ctrl = True;
 RD_BOOL g_encryption = True;
+RD_BOOL g_encryption_initial = True;
 RD_BOOL g_packet_encryption = True;
 RD_BOOL g_desktop_save = True;	/* desktop save order */
 RD_BOOL g_polygon_ellipse_orders = True;	/* polygon / ellipse orders */
 RD_BOOL g_fullscreen = False;
 RD_BOOL g_grab_keyboard = True;
 RD_BOOL g_hide_decorations = False;
-RD_BOOL g_use_rdp5 = True;
+RDP_VERSION g_rdp_version = RDP_V5;	/* Default to version 5 */
 RD_BOOL g_rdpclip = True;
 RD_BOOL g_console_session = False;
 #ifndef VBOX
@@ -111,22 +125,34 @@ RD_BOOL g_lspci_enabled = False;
 RD_BOOL g_owncolmap = False;
 RD_BOOL g_ownbackstore = True;	/* We can't rely on external BackingStore */
 RD_BOOL g_seamless_rdp = False;
+RD_BOOL g_use_password_as_pin = False;
+char g_seamless_shell[512];
+char g_seamless_spawn_cmd[512];
+RD_BOOL g_seamless_persistent_mode = True;
 RD_BOOL g_user_quit = False;
 uint32 g_embed_wnd;
 uint32 g_rdp5_performanceflags =
-	RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
+	RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS | RDP5_NO_CURSOR_SHADOW;
 /* Session Directory redirection */
 RD_BOOL g_redirect = False;
-char g_redirect_server[64];
-char g_redirect_domain[16];
-char g_redirect_password[64];
+char *g_redirect_server;
+uint32 g_redirect_server_len;
+char *g_redirect_domain;
+uint32 g_redirect_domain_len;
 char *g_redirect_username;
-char g_redirect_cookie[128];
+uint32 g_redirect_username_len;
+uint8 *g_redirect_lb_info;
+uint32 g_redirect_lb_info_len;
+uint8 *g_redirect_cookie;
+uint32 g_redirect_cookie_len;
 uint32 g_redirect_flags = 0;
+uint32 g_redirect_session_id = 0;
 
 uint32 g_reconnect_logonid = 0;
 char g_reconnect_random[16];
+time_t g_reconnect_random_ts;
 RD_BOOL g_has_reconnect_random = False;
+RD_BOOL g_reconnect_loop = False;
 uint8 g_client_random[SEC_RANDOM_SIZE];
 RD_BOOL g_pending_resize = False;
 
@@ -146,6 +172,11 @@ RD_BOOL g_keep_virtual_desktop_shortcuts = False;
 char g_codepage[16] = "";
 #endif
 
+char *g_sc_csp_name = NULL;	/* Smartcard CSP name  */
+char *g_sc_reader_name = NULL;
+char *g_sc_card_name = NULL;
+char *g_sc_container_name = NULL;
+
 extern RDPDR_DEVICE g_rdpdr_device[];
 extern uint32 g_num_devices;
 extern char *g_rdpdr_clientname;
@@ -176,18 +207,21 @@ usage(char *program)
 #endif
 	fprintf(stderr, "   -u: user name\n");
 	fprintf(stderr, "   -d: domain\n");
-	fprintf(stderr, "   -s: shell\n");
+	fprintf(stderr, "   -s: shell / seamless application to start remotly\n");
 	fprintf(stderr, "   -c: working directory\n");
 	fprintf(stderr, "   -p: password (- to prompt)\n");
 	fprintf(stderr, "   -n: client hostname\n");
 	fprintf(stderr, "   -k: keyboard layout on server (en-us, de, sv, etc.)\n");
 	fprintf(stderr, "   -g: desktop geometry (WxH)\n");
+#ifdef WITH_SCARD
+	fprintf(stderr, "   -i: enables smartcard authentication, password is used as pin\n");
+#endif
 	fprintf(stderr, "   -f: full-screen mode\n");
 	fprintf(stderr, "   -b: force bitmap updates\n");
 #ifdef HAVE_ICONV
 	fprintf(stderr, "   -L: local codepage\n");
 #endif
-	fprintf(stderr, "   -A: enable SeamlessRDP mode\n");
+	fprintf(stderr, "   -A: path to SeamlessRDP shell, this enables SeamlessRDP mode\n");
 	fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");
 	fprintf(stderr, "   -e: disable encryption (French TS)\n");
 	fprintf(stderr, "   -E: disable encryption from client to server\n");
@@ -197,6 +231,7 @@ usage(char *program)
 	fprintf(stderr, "   -K: keep window manager key bindings\n");
 	fprintf(stderr, "   -S: caption button size (single application mode)\n");
 	fprintf(stderr, "   -T: window title\n");
+	fprintf(stderr, "   -t: disable use of remote ctrl\n");
 	fprintf(stderr, "   -N: enable numlock syncronization\n");
 	fprintf(stderr, "   -X: embed into another window with a given id.\n");
 	fprintf(stderr, "   -a: connection colour depth\n");
@@ -255,9 +290,24 @@ usage(char *program)
 	fprintf(stderr, "   -4: use RDP version 4\n");
 	fprintf(stderr, "   -5: use RDP version 5 (default)\n");
 #ifdef WITH_BIRD_VD_HACKS
-	fprintf(stderr, "   -H keep-virtual-desktop-shortcuts: Keep keyboard shortcuts typical\n"
-	                "      for switching virtual desktops (C-A-Left/Right). \n");
+    fprintf(stderr, "   -H keep-virtual-desktop-shortcuts: Keep keyboard shortcuts typical\n"
+                    "      for switching virtual desktops (C-A-Left/Right). \n");
+#endif
+#ifdef WITH_SCARD
+	fprintf(stderr, "   -o: name=value: Adds an additional option to rdesktop.\n");
+	fprintf(stderr,
+		"           sc-csp-name        Specifies the Crypto Service Provider name which\n");
+	fprintf(stderr,
+		"                              is used to authenticate the user by smartcard\n");
+	fprintf(stderr,
+		"           sc-container-name  Specifies the container name, this is usally the username\n");
+	fprintf(stderr, "           sc-reader-name     Smartcard reader name to use\n");
+	fprintf(stderr,
+		"           sc-card-name       Specifies the card name of the smartcard to use\n");
 #endif
+
+	fprintf(stderr, "\n");
+
 }
 
 static int
@@ -277,7 +327,6 @@ handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
 			break;
 
 		case exDiscReasonAPIInitiatedDisconnect:
-		case exDiscReasonWindows7Disconnect:
 			text = "Server initiated disconnect";
 			retval = EXRD_API_DISCONNECT;
 			break;
@@ -317,6 +366,26 @@ handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
 			retval = EXRD_DENIED_FIPS;
 			break;
 
+		case exDiscReasonServerInsufficientPrivileges:
+			text = "The user cannot connect to the server due to insufficient access privileges.";
+			retval = EXRD_INSUFFICIENT_PRIVILEGES;
+			break;
+
+		case exDiscReasonServerFreshCredentialsRequired:
+			text = "The server does not accept saved user credentials and requires that the user enter their credentials for each connection.";
+			retval = EXRD_FRESH_CREDENTIALS_REQUIRED;
+			break;
+
+		case exDiscReasonRPCInitiatedDisconnectByUser:
+			text = "Disconnect initiated by administration tool";
+			retval = EXRD_RPC_DISCONNECT_BY_USER;
+			break;
+
+		case exDiscReasonByUser:
+			text = "Disconnect initiated by user";
+			retval = EXRD_DISCONNECT_BY_USER;
+			break;
+
 		case exDiscReasonLicenseInternal:
 			text = "Internal licensing error";
 			retval = EXRD_LIC_INTERNAL;
@@ -358,7 +427,7 @@ handle_disconnect_reason(RD_BOOL deactivated, uint16 reason)
 			break;
 
 		case exDiscReasonLicenseErrClientEncryption:
-			text = "Incorrect client license enryption";
+			text = "Incorrect client license encryption";
 			retval = EXRD_LIC_ENC;
 			break;
 
@@ -497,10 +566,9 @@ DECLEXPORT(PRTLOGGER) RTLogDefaultInit(void)
 int
 main(int argc, char *argv[])
 {
-	char server[64];
+	char server[256];
 	char fullhostname[64];
 	char domain[256];
-	char password[64];
 	char shell[256];
 	char directory[256];
 	RD_BOOL prompt_password, deactivated;
@@ -533,9 +601,12 @@ main(int argc, char *argv[])
 	act.sa_flags = 0;
 	sigaction(SIGPIPE, &act, NULL);
 
-	flags = RDP_LOGON_NORMAL;
+	/* setup default flags for TS_INFO_PACKET */
+	flags = RDP_INFO_MOUSE | RDP_INFO_DISABLECTRLALTDEL
+		| RDP_INFO_UNICODE | RDP_INFO_MAXIMIZESHELL | RDP_INFO_ENABLEWINDOWSKEY;
+
 	prompt_password = False;
-	domain[0] = password[0] = shell[0] = directory[0] = 0;
+	g_seamless_spawn_cmd[0] = domain[0] = g_password[0] = shell[0] = directory[0] = 0;
 	g_embed_wnd = 0;
 
 	g_num_devices = 0;
@@ -552,7 +623,7 @@ main(int argc, char *argv[])
 #endif
 
 	while ((c = getopt(argc, argv,
-			   VNCOPT VDHOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
+			   VNCOPT VDHOPT "A:u:L:d:s:c:p:n:k:g:o:fbBeEitmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
 	{
 		switch (c)
 		{
@@ -572,6 +643,7 @@ main(int argc, char *argv[])
 
 			case 'A':
 				g_seamless_rdp = True;
+				STRNCPY(g_seamless_shell, optarg, sizeof(g_seamless_shell));
 				break;
 
 			case 'u':
@@ -594,6 +666,7 @@ main(int argc, char *argv[])
 
 			case 's':
 				STRNCPY(shell, optarg, sizeof(shell));
+				g_seamless_persistent_mode = False;
 				break;
 
 			case 'c':
@@ -607,14 +680,23 @@ main(int argc, char *argv[])
 					break;
 				}
 
-				STRNCPY(password, optarg, sizeof(password));
-				flags |= RDP_LOGON_AUTO;
+				STRNCPY(g_password, optarg, sizeof(g_password));
+				flags |= RDP_INFO_AUTOLOGON;
 
 				/* try to overwrite argument so it won't appear in ps */
 				p = optarg;
 				while (*p)
 					*(p++) = 'X';
 				break;
+#ifdef WITH_SCARD
+			case 'i':
+				flags |= RDP_INFO_PASSWORD_IS_SC_PIN;
+				g_use_password_as_pin = True;
+				break;
+#endif
+			case 't':
+				g_use_ctrl = False;
+				break;
 
 			case 'n':
 				STRNCPY(g_hostname, optarg, sizeof(g_hostname));
@@ -683,7 +765,7 @@ main(int argc, char *argv[])
 				break;
 
 			case 'e':
-				g_encryption = False;
+				g_encryption_initial = g_encryption = False;
 				break;
 			case 'E':
 				g_packet_encryption = False;
@@ -747,27 +829,30 @@ main(int argc, char *argv[])
 
 			case 'z':
 				DEBUG(("rdp compression enabled\n"));
-				flags |= (RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2);
+				flags |= (RDP_INFO_COMPRESSION | RDP_INFO_COMPRESSION2);
 				break;
 
 			case 'x':
 				if (str_startswith(optarg, "m"))	/* modem */
 				{
-					g_rdp5_performanceflags =
+					g_rdp5_performanceflags = RDP5_NO_CURSOR_SHADOW |
 						RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
 						RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
 				}
 				else if (str_startswith(optarg, "b"))	/* broadband */
 				{
-					g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
+					g_rdp5_performanceflags =
+						RDP5_NO_CURSOR_SHADOW | RDP5_NO_WALLPAPER;
 				}
 				else if (str_startswith(optarg, "l"))	/* lan */
 				{
-					g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
+					g_rdp5_performanceflags =
+						RDP5_NO_CURSOR_SHADOW | RDP5_DISABLE_NOTHING;
 				}
 				else
 				{
-					g_rdp5_performanceflags = strtol(optarg, NULL, 16);
+					g_rdp5_performanceflags =
+						RDP5_NO_CURSOR_SHADOW | strtol(optarg, NULL, 16);
 				}
 				break;
 
@@ -787,7 +872,7 @@ main(int argc, char *argv[])
 						while ((p = next_arg(optarg, ',')))
 						{
 							if (str_startswith(optarg, "remote"))
-								flags |= RDP_LOGON_LEAVE_AUDIO;
+								flags |= RDP_INFO_REMOTE_CONSOLE_AUDIO;
 
 							if (str_startswith(optarg, "local"))
 #ifdef WITH_RDPSND
@@ -889,12 +974,41 @@ main(int argc, char *argv[])
 				break;
 
 			case '4':
-				g_use_rdp5 = False;
+				g_rdp_version = RDP_V4;
 				break;
 
 			case '5':
-				g_use_rdp5 = True;
+				g_rdp_version = RDP_V5;
 				break;
+#if WITH_SCARD
+			case 'o':
+				{
+					char *p = strchr(optarg, '=');
+					if (p == NULL)
+					{
+						warning("Skipping option '%s' specified, lacks name=value format.\n");
+						continue;
+					}
+
+					if (strncmp(optarg, "sc-csp-name", strlen("sc-scp-name")) ==
+					    0)
+						g_sc_csp_name = strdup(p + 1);
+					else if (strncmp
+						 (optarg, "sc-reader-name",
+						  strlen("sc-reader-name")) == 0)
+						g_sc_reader_name = strdup(p + 1);
+					else if (strncmp
+						 (optarg, "sc-card-name",
+						  strlen("sc-card-name")) == 0)
+						g_sc_card_name = strdup(p + 1);
+					else if (strncmp
+						 (optarg, "sc-container-name",
+						  strlen("sc-container-name")) == 0)
+						g_sc_container_name = strdup(p + 1);
+
+				}
+				break;
+#endif
 
 #ifdef WITH_BIRD_VD_HACKS
 			case 'H': /* hacks */
@@ -924,6 +1038,11 @@ main(int argc, char *argv[])
 
 	if (g_seamless_rdp)
 	{
+		if (shell[0])
+			STRNCPY(g_seamless_spawn_cmd, shell, sizeof(g_seamless_spawn_cmd));
+
+		STRNCPY(shell, g_seamless_shell, sizeof(shell));
+
 		if (g_win_button_size)
 		{
 			error("You cannot use -S and -A at the same time\n");
@@ -950,7 +1069,7 @@ main(int argc, char *argv[])
 			error("You cannot use -X and -A at the same time\n");
 			return EX_USAGE;
 		}
-		if (!g_use_rdp5)
+		if (g_rdp_version < RDP_V5)
 		{
 			error("You cannot use -4 and -A at the same time\n");
 			return EX_USAGE;
@@ -1017,8 +1136,8 @@ main(int argc, char *argv[])
 		xfree(locale);
 
 
-	if (prompt_password && read_password(password, sizeof(password)))
-		flags |= RDP_LOGON_AUTO;
+	if (prompt_password && read_password(g_password, sizeof(g_password)))
+		flags |= RDP_INFO_AUTOLOGON;
 
 	if (g_title[0] == 0)
 	{
@@ -1027,19 +1146,38 @@ main(int argc, char *argv[])
 	}
 
 #ifdef RDP2VNC
-	rdp2vnc_connect(server, flags, domain, password, shell, directory);
+	rdp2vnc_connect(server, flags, domain, g_password, shell, directory);
 	return EX_OK;
 #else
 
+	/* Only startup ctrl functionality is seamless are used for now. */
+	if (g_use_ctrl && g_seamless_rdp)
+	{
+		if (ctrl_init(server, domain, g_username) < 0)
+		{
+			error("Failed to initialize ctrl mode.");
+			exit(1);
+		}
+
+		if (ctrl_is_slave())
+		{
+			fprintf(stdout,
+				"rdesktop in slave mode sending command to master process.\n");
+
+			if (g_seamless_spawn_cmd[0])
+				return ctrl_send_command("seamless.spawn", g_seamless_spawn_cmd);
+
+			fprintf(stdout, "No command specified to be spawn in seamless mode.\n");
+			return EX_USAGE;
+		}
+	}
+
 	if (!ui_init())
 		return EX_OSERR;
 
 #ifdef WITH_RDPSND
-	if (g_rdpsnd)
-	{
-		if (!rdpsnd_init(rdpsnd_optarg))
-			warning("Initializing sound-support failed!\n");
-	}
+	if (!rdpsnd_init(rdpsnd_optarg))
+		warning("Initializing sound-support failed!\n");
 #endif
 
 #ifdef WITH_RDPUSB
@@ -1051,7 +1189,7 @@ main(int argc, char *argv[])
 		lspci_init();
 
 	rdpdr_init();
-
+	g_reconnect_loop = False;
 	while (1)
 	{
 		rdesktop_reset_state();
@@ -1061,44 +1199,89 @@ main(int argc, char *argv[])
 			STRNCPY(domain, g_redirect_domain, sizeof(domain));
 			xfree(g_username);
 			g_username = (char *) xmalloc(strlen(g_redirect_username) + 1);
-			STRNCPY(g_username, g_redirect_username, sizeof(g_username));
-			STRNCPY(password, g_redirect_password, sizeof(password));
+			STRNCPY(g_username, g_redirect_username, strlen(g_redirect_username) + 1);
 			STRNCPY(server, g_redirect_server, sizeof(server));
-			flags |= RDP_LOGON_AUTO;
+			flags |= RDP_INFO_AUTOLOGON;
+
+			fprintf(stderr, "Redirected to %s@%s session %d.\n",
+				g_redirect_username, g_redirect_server, g_redirect_session_id);
+
+			/* A redirect on SSL from a 2003 WTS will result in a 'connection reset by peer'
+			   and therefor we just clear this error before we connect to redirected server.
+			 */
+			g_network_error = False;
+			g_redirect = False;
 		}
 
 		ui_init_connection();
-		if (!rdp_connect(server, flags, domain, password, shell, directory, g_redirect))
-			return EX_PROTOCOL;
+		if (!rdp_connect
+		    (server, flags, domain, g_password, shell, directory, g_reconnect_loop))
+		{
+
+			g_network_error = False;
+
+			if (g_reconnect_loop == False)
+				return EX_PROTOCOL;
+
+			/* check if auto reconnect cookie has timed out */
+			if (time(NULL) - g_reconnect_random_ts > RECONNECT_TIMEOUT)
+			{
+				fprintf(stderr, "Tried to reconnect for %d minutes, giving up.\n",
+					RECONNECT_TIMEOUT / 60);
+				return EX_PROTOCOL;
+			}
+
+			sleep(4);
+			continue;
+		}
+
+		if (g_redirect)
+		{
+			rdp_disconnect();
+			continue;
+		}
 
 		/* By setting encryption to False here, we have an encrypted login 
 		   packet but unencrypted transfer of other packets */
 		if (!g_packet_encryption)
-			g_encryption = False;
-
+			g_encryption_initial = g_encryption = False;
 
 		DEBUG(("Connection successful.\n"));
-		memset(password, 0, sizeof(password));
 
-		if (!g_redirect)
-			if (!ui_create_window())
-				return EX_OSERR;
+		rd_create_ui();
+		tcp_run_ui(True);
 
-		g_redirect = False;
+		deactivated = False;
+		g_reconnect_loop = False;
 		rdp_main_loop(&deactivated, &ext_disc_reason);
 
+		tcp_run_ui(False);
+
 		DEBUG(("Disconnecting...\n"));
 		rdp_disconnect();
 
 		if (g_redirect)
 			continue;
 
+		/* handle network error and start autoreconnect */
+		if (g_network_error && !deactivated)
+		{
+			fprintf(stderr,
+				"Disconnected due to network error, retrying to reconnect for %d minutes.\n",
+				RECONNECT_TIMEOUT / 60);
+			g_network_error = False;
+			g_reconnect_loop = True;
+			continue;
+		}
+
 		ui_seamless_end();
 		ui_destroy_window();
+
+		/* Enter a reconnect loop if we have a pending resize request */
 		if (g_pending_resize)
 		{
-			/* If we have a pending resize, reconnect using the new size, rather than exit */
 			g_pending_resize = False;
+			g_reconnect_loop = True;
 			continue;
 		}
 		break;
@@ -1168,7 +1351,7 @@ generate_random(uint8 * random)
 {
 	struct stat st;
 	struct tms tmsbuf;
-	SSL_MD5 md5;
+	RDSSL_MD5 md5;
 	uint32 *r;
 	int fd, n;
 
@@ -1200,11 +1383,11 @@ generate_random(uint8 * random)
 	r[7] = st.st_ctime;
 
 	/* Hash both halves with MD5 to obscure possible patterns */
-	ssl_md5_init(&md5);
-	ssl_md5_update(&md5, random, 16);
-	ssl_md5_final(&md5, random);
-	ssl_md5_update(&md5, random + 16, 16);
-	ssl_md5_final(&md5, random + 16);
+	rdssl_md5_init(&md5);
+	rdssl_md5_update(&md5, random, 16);
+	rdssl_md5_final(&md5, random);
+	rdssl_md5_update(&md5, random + 16, 16);
+	rdssl_md5_final(&md5, random + 16);
 }
 
 /* malloc; exit if out of memory */
@@ -1571,11 +1754,11 @@ l_to_a(long N, int base)
 	return ret;
 }
 
-
 int
 load_licence(unsigned char **data)
 {
-	char *home, *path;
+	uint8 ho[20], hi[16];
+	char *home, path[PATH_MAX], hash[41];
 	struct stat st;
 	int fd, length;
 
@@ -1583,48 +1766,67 @@ load_licence(unsigned char **data)
 	if (home == NULL)
 		return -1;
 
-	path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
-	sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
+	memset(hi, 0, sizeof(hi));
+	snprintf((char *) hi, 16, "%s", g_hostname);
+	sec_hash_sha1_16(ho, hi, g_static_rdesktop_salt_16);
+	sec_hash_to_string(hash, sizeof(hash), ho, sizeof(ho));
+
+	snprintf(path, PATH_MAX, "%s" RDESKTOP_LICENSE_STORE "/%s.cal", home, hash);
+	path[sizeof(path) - 1] = '\0';
 
 	fd = open(path, O_RDONLY);
 	if (fd == -1)
-		return -1;
+	{
+		/* fallback to try reading old license file */
+		snprintf(path, PATH_MAX, "%s/.rdesktop/license.%s", home, g_hostname);
+		path[sizeof(path) - 1] = '\0';
+		if ((fd = open(path, O_RDONLY)) == -1)
+			return -1;
+	}
 
 	if (fstat(fd, &st))
+	{
+		close(fd);
 		return -1;
+	}
 
 	*data = (uint8 *) xmalloc(st.st_size);
 	length = read(fd, *data, st.st_size);
 	close(fd);
-	xfree(path);
 	return length;
 }
 
 void
 save_licence(unsigned char *data, int length)
 {
-	char *home, *path, *tmppath;
+	uint8 ho[20], hi[16];
+	char *home, path[PATH_MAX], tmppath[PATH_MAX], hash[41];
 	int fd;
 
 	home = getenv("HOME");
 	if (home == NULL)
 		return;
 
-	path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence."));
-
-	sprintf(path, "%s/.rdesktop", home);
-	if ((mkdir(path, 0700) == -1) && errno != EEXIST)
+	snprintf(path, PATH_MAX, "%s" RDESKTOP_LICENSE_STORE, home);
+	path[sizeof(path) - 1] = '\0';
+	if (utils_mkdir_p(path, 0700) == -1)
 	{
 		perror(path);
 		return;
 	}
 
-	/* write licence to licence.hostname.new, then atomically rename to licence.hostname */
+	memset(hi, 0, sizeof(hi));
+	snprintf((char *) hi, 16, "%s", g_hostname);
+	sec_hash_sha1_16(ho, hi, g_static_rdesktop_salt_16);
+	sec_hash_to_string(hash, sizeof(hash), ho, sizeof(ho));
+
+	/* write licence to {sha1}.cal.new, then atomically 
+	   rename to {sha1}.cal */
+	snprintf(path, PATH_MAX, "%s" RDESKTOP_LICENSE_STORE "/%s.cal", home, hash);
+	path[sizeof(path) - 1] = '\0';
 
-	sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
-	tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
-	strcpy(tmppath, path);
-	strcat(tmppath, ".new");
+	snprintf(tmppath, PATH_MAX, "%s.new", path);
+	path[sizeof(path) - 1] = '\0';
 
 	fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
 	if (fd == -1)
@@ -1645,8 +1847,18 @@ save_licence(unsigned char *data, int length)
 	}
 
 	close(fd);
-	xfree(tmppath);
-	xfree(path);
+}
+
+/* create rdesktop ui */
+void
+rd_create_ui()
+{
+	/* only create a window if we dont have one intialized */
+	if (!ui_have_window())
+	{
+		if (!ui_create_window())
+			exit(EX_OSERR);
+	}
 }
 
 /* Create the bitmap cache directory */
diff --git a/src/VBox/RDP/client/rdesktop.h b/src/VBox/RDP/client-1.8.3/rdesktop.h
similarity index 97%
rename from src/VBox/RDP/client/rdesktop.h
rename to src/VBox/RDP/client-1.8.3/rdesktop.h
index 72f9da7..40b4785 100644
--- a/src/VBox/RDP/client/rdesktop.h
+++ b/src/VBox/RDP/client-1.8.3/rdesktop.h
@@ -109,6 +109,10 @@
 #define EXRD_OUT_OF_MEM 6
 #define EXRD_DENIED 7
 #define EXRD_DENIED_FIPS 8
+#define EXRD_INSUFFICIENT_PRIVILEGES 9
+#define EXRD_FRESH_CREDENTIALS_REQUIRED 10
+#define EXRD_RPC_DISCONNECT_BY_USER 11
+#define EXRD_DISCONNECT_BY_USER 12
 #define EXRD_LIC_INTERNAL 16
 #define EXRD_LIC_NOSERVER 17
 #define EXRD_LIC_NOLICENSE 18
diff --git a/src/VBox/RDP/client/rdesktop.spec b/src/VBox/RDP/client-1.8.3/rdesktop.spec
similarity index 92%
rename from src/VBox/RDP/client/rdesktop.spec
rename to src/VBox/RDP/client-1.8.3/rdesktop.spec
index fc81d54..f9b2f54 100644
--- a/src/VBox/RDP/client/rdesktop.spec
+++ b/src/VBox/RDP/client-1.8.3/rdesktop.spec
@@ -1,6 +1,6 @@
 Summary: Remote Desktop Protocol client
 Name: rdesktop
-Version: 1.7.0
+Version: 1.8.3
 Release: 1
 License: GPL; see COPYING
 Group: Applications/Communications
@@ -11,7 +11,7 @@ Packager: Peter Åstrand <astrand at cendio.se>
 %description
 rdesktop is a client for Remote Desktop Protocol (RDP), used in a number of
 Microsoft products including Windows NT Terminal Server, Windows 2000 Server,
-Windows XP and Windows 2003 Server.
+Windows XP, Windows 2003 Server and Windows 2008r2.
 
 %prep
 rm -rf $RPM_BUILD_ROOT
diff --git a/src/VBox/RDP/client/rdp.c b/src/VBox/RDP/client-1.8.3/rdp.c
similarity index 82%
rename from src/VBox/RDP/client/rdp.c
rename to src/VBox/RDP/client-1.8.3/rdp.c
index 9d0a101..01fdf22 100644
--- a/src/VBox/RDP/client/rdp.c
+++ b/src/VBox/RDP/client-1.8.3/rdp.c
@@ -3,6 +3,7 @@
    Protocol services - RDP layer
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
    Copyright 2003-2011 Peter Astrand <astrand at cendio.se> for Cendio AB
+   Copyright 2011-2014 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -64,13 +65,14 @@
 
 extern uint16 g_mcs_userid;
 extern char *g_username;
+extern char g_password[64];
 extern char g_codepage[16];
 extern RD_BOOL g_bitmap_compression;
 extern RD_BOOL g_orders;
 extern RD_BOOL g_encryption;
 extern RD_BOOL g_desktop_save;
 extern RD_BOOL g_polygon_ellipse_orders;
-extern RD_BOOL g_use_rdp5;
+extern RDP_VERSION g_rdp_version;
 extern uint16 g_server_rdp_version;
 extern uint32 g_rdp5_performanceflags;
 extern int g_server_depth;
@@ -80,6 +82,7 @@ extern RD_BOOL g_bitmap_cache;
 extern RD_BOOL g_bitmap_cache_persist_enable;
 extern RD_BOOL g_numlock_sync;
 extern RD_BOOL g_pending_resize;
+extern RD_BOOL g_network_error;
 
 uint8 *g_next_packet;
 uint32 g_rdp_shareid;
@@ -88,16 +91,24 @@ extern RDPCOMP g_mppc_dict;
 
 /* Session Directory support */
 extern RD_BOOL g_redirect;
-extern char g_redirect_server[64];
-extern char g_redirect_domain[16];
-extern char g_redirect_password[64];
+extern char *g_redirect_server;
+extern uint32 g_redirect_server_len;
+extern char *g_redirect_domain;
+extern uint32 g_redirect_domain_len;
 extern char *g_redirect_username;
-extern char g_redirect_cookie[128];
+extern uint32 g_redirect_username_len;
+extern uint8 *g_redirect_lb_info;
+extern uint32 g_redirect_lb_info_len;
+extern uint8 *g_redirect_cookie;
+extern uint32 g_redirect_cookie_len;
 extern uint32 g_redirect_flags;
+extern uint32 g_redirect_session_id;
+
 /* END Session Directory support */
 
 extern uint32 g_reconnect_logonid;
 extern char g_reconnect_random[16];
+extern time_t g_reconnect_random_ts;
 extern RD_BOOL g_has_reconnect_random;
 extern uint8 g_client_random[SEC_RANDOM_SIZE];
 
@@ -204,6 +215,9 @@ rdp_send_data(STREAM s, uint8 data_pdu_type)
 void
 rdp_out_unistr(STREAM s, char *string, int len)
 {
+	if (string == NULL || len == 0)
+		return;
+
 #ifdef HAVE_ICONV
 	size_t ibl = strlen(string), obl = len + 2;
 	static iconv_t iconv_h = (iconv_t) - 1;
@@ -275,12 +289,16 @@ rdp_out_unistr(STREAM s, char *string, int len)
  *
  * Returns str_len of string
  */
-int
-rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
+void
+rdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size)
 {
+	/* Dynamic allocate of destination string if not provided */
+	*string = xmalloc(in_len * 2);
+	*str_size = in_len * 2;
+
 #ifdef HAVE_ICONV
-	size_t ibl = in_len, obl = str_size - 1;
-	char *pin = (char *) s->p, *pout = string;
+	size_t ibl = in_len, obl = *str_size - 1;
+	char *pin = (char *) s->p, *pout = *string;
 	static iconv_t iconv_h = (iconv_t) - 1;
 
 	if (g_iconv_works)
@@ -293,7 +311,7 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
 					WINDOWS_CODEPAGE, g_codepage, iconv_h);
 
 				g_iconv_works = False;
-				return rdp_in_unistr(s, string, str_size, in_len);
+				return rdp_in_unistr(s, in_len, string, str_size);
 			}
 		}
 
@@ -305,12 +323,11 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
 			}
 			else
 			{
-				iconv_close(iconv_h);
-				iconv_h = (iconv_t) - 1;
 				warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
 
-				g_iconv_works = False;
-				return rdp_in_unistr(s, string, str_size, in_len);
+				free(*string);
+				*string = NULL;
+				*str_size = 0;
 			}
 		}
 
@@ -318,19 +335,21 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
 		s->p += in_len;
 
 		*pout = 0;
-		return pout - string;
+
+		if (*string)
+			*str_size = pout - *string;
 	}
 	else
 #endif
 	{
 		int i = 0;
-		int len = in_len / 2;
 		int rem = 0;
+		uint32 len = in_len / 2;
 
-		if (len > str_size - 1)
+		if (len > *str_size - 1)
 		{
 			warning("server sent an unexpectedly long string, truncating\n");
-			len = str_size - 1;
+			len = *str_size - 1;
 			rem = in_len - 2 * len;
 		}
 
@@ -342,7 +361,7 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
 
 		in_uint8s(s, rem);
 		string[len] = 0;
-		return len;
+		*str_size = len;
 	}
 }
 
@@ -353,13 +372,17 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
 		    char *password, char *program, char *directory)
 {
 	char *ipaddr = tcp_get_address();
+	/* length of string in TS_INFO_PACKET excludes null terminator */
 	int len_domain = 2 * strlen(domain);
 	int len_user = 2 * strlen(user);
 	int len_password = 2 * strlen(password);
 	int len_program = 2 * strlen(program);
 	int len_directory = 2 * strlen(directory);
-	int len_ip = 2 * strlen(ipaddr);
-	int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
+
+	/* length of strings in TS_EXTENDED_PACKET includes null terminator */
+	int len_ip = 2 * strlen(ipaddr) + 2;
+	int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll") + 2;
+
 	int packetlen = 0;
 	uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
 	STREAM s;
@@ -367,7 +390,7 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
 	time_t tzone;
 	uint8 security_verifier[16];
 
-	if (!g_use_rdp5 || 1 == g_server_rdp_version)
+	if (g_rdp_version == RDP_V4 || 1 == g_server_rdp_version)
 	{
 		DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
 
@@ -390,85 +413,101 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
 	else
 	{
 
-		flags |= RDP_LOGON_BLOB;
 		DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
-		packetlen = 4 +	/* Unknown uint32 */
+
+		if (g_redirect == True && g_redirect_cookie_len > 0)
+		{
+			len_password = g_redirect_cookie_len;
+			len_password -= 2;	/* substract 2 bytes which is added below */
+		}
+
+		packetlen =
+			/* size of TS_INFO_PACKET */
+			4 +	/* CodePage */
 			4 +	/* flags */
-			2 +	/* len_domain */
-			2 +	/* len_user */
-			(flags & RDP_LOGON_AUTO ? 2 : 0) +	/* len_password */
-			(flags & RDP_LOGON_BLOB ? 2 : 0) +	/* Length of BLOB */
-			2 +	/* len_program */
-			2 +	/* len_directory */
-			(0 < len_domain ? len_domain : 2) +	/* domain */
-			len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +	/* We have no 512 byte BLOB. Perhaps we must? */
-			(flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) +	/* After the BLOB is a unknown int16. If there is a BLOB, that is. */
-			(0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +	/* Unknown (2) */
-			2 +	/* Client ip length */
-			len_ip +	/* Client ip */
-			2 +	/* DLL string length */
-			len_dll +	/* DLL string */
-			2 +	/* Unknown */
-			2 +	/* Unknown */
-			64 +	/* Time zone #0 */
-			2 +	/* Unknown */
-			64 +	/* Time zone #1 */
-			32;	/* Unknown */
+			2 +	/* cbDomain */
+			2 +	/* cbUserName */
+			2 +	/* cbPassword */
+			2 +	/* cbAlternateShell */
+			2 +	/* cbWorkingDir */
+			2 + len_domain +	/* Domain */
+			2 + len_user +	/* UserName */
+			2 + len_password +	/* Password */
+			2 + len_program +	/* AlternateShell */
+			2 + len_directory +	/* WorkingDir */
+			/* size of TS_EXTENDED_INFO_PACKET */
+			2 +	/* clientAdressFamily */
+			2 +	/* cbClientAdress */
+			len_ip +	/* clientAddress */
+			2 +	/* cbClientDir */
+			len_dll +	/* clientDir */
+			/* size of TS_TIME_ZONE_INFORMATION */
+			4 +	/* Bias, (UTC = local time + bias */
+			64 +	/* StandardName, 32 unicode char array, Descriptive standard time on client */
+			16 +	/* StandardDate */
+			4 +	/* StandardBias */
+			64 +	/* DaylightName, 32 unicode char array */
+			16 +	/* DaylightDate */
+			4 +	/* DaylightBias */
+			4 +	/* clientSessionId */
+			4 +	/* performanceFlags */
+			2 +	/* cbAutoReconnectCookie, either 0 or 0x001c */
+			/* size of ARC_CS_PRIVATE_PACKET */
+			28;	/* autoReconnectCookie */
+
 
 		s = sec_init(sec_flags, packetlen);
 		DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
 
-		out_uint32(s, 0);	/* Unknown */
+		/* TS_INFO_PACKET */
+		out_uint32(s, 0);	/* Code Page */
 		out_uint32_le(s, flags);
 		out_uint16_le(s, len_domain);
 		out_uint16_le(s, len_user);
-		if (flags & RDP_LOGON_AUTO)
-		{
-			out_uint16_le(s, len_password);
-
-		}
-		if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
-		{
-			out_uint16_le(s, 0);
-		}
+		out_uint16_le(s, len_password);
 		out_uint16_le(s, len_program);
 		out_uint16_le(s, len_directory);
+
 		if (0 < len_domain)
 			rdp_out_unistr(s, domain, len_domain);
 		else
-			out_uint16_le(s, 0);
-		rdp_out_unistr(s, user, len_user);
-		if (flags & RDP_LOGON_AUTO)
-		{
-			rdp_out_unistr(s, password, len_password);
-		}
-		if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
+			out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */
+
+		if (0 < len_user)
+			rdp_out_unistr(s, user, len_user);
+		else
+			out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */
+
+		if (0 < len_password)
 		{
-			out_uint16_le(s, 0);
+			if (g_redirect == True && 0 < g_redirect_cookie_len)
+			{
+				out_uint8p(s, g_redirect_cookie, g_redirect_cookie_len);
+			}
+			else
+			{
+				rdp_out_unistr(s, password, len_password);
+			}
 		}
+		else
+			out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */
+
 		if (0 < len_program)
-		{
 			rdp_out_unistr(s, program, len_program);
-
-		}
 		else
-		{
-			out_uint16_le(s, 0);
-		}
+			out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */
+
 		if (0 < len_directory)
-		{
 			rdp_out_unistr(s, directory, len_directory);
-		}
 		else
-		{
-			out_uint16_le(s, 0);
-		}
+			out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */
+
 		/* TS_EXTENDED_INFO_PACKET */
 		out_uint16_le(s, 2);	/* clientAddressFamily = AF_INET */
-		out_uint16_le(s, len_ip + 2);	/* cbClientAddress, Length of client ip */
-		rdp_out_unistr(s, ipaddr, len_ip);	/* clientAddress */
-		out_uint16_le(s, len_dll + 2);	/* cbClientDir */
-		rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);	/* clientDir */
+		out_uint16_le(s, len_ip);	/* cbClientAddress, Length of client ip */
+		rdp_out_unistr(s, ipaddr, len_ip - 2);	/* clientAddress */
+		out_uint16_le(s, len_dll);	/* cbClientDir */
+		rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll - 2);	/* clientDir */
 
 		/* TS_TIME_ZONE_INFORMATION */
 		tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
@@ -489,7 +528,7 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
 		out_uint32_le(s, 0xffffffc4);	/* DaylightBias */
 
 		/* Rest of TS_EXTENDED_INFO_PACKET */
-		out_uint32_le(s, 0xfffffffe);	/* clientSessionId, consider changing to 0 */
+		out_uint32_le(s, 0);	/* clientSessionId (Ignored by server MUST be 0) */
 		out_uint32_le(s, g_rdp5_performanceflags);
 
 		/* Client Auto-Reconnect */
@@ -500,8 +539,8 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
 			out_uint32_le(s, 28);	/* cbLen */
 			out_uint32_le(s, 1);	/* Version */
 			out_uint32_le(s, g_reconnect_logonid);	/* LogonId */
-			ssl_hmac_md5(g_reconnect_random, sizeof(g_reconnect_random),
-				     g_client_random, SEC_RANDOM_SIZE, security_verifier);
+			rdssl_hmac_md5(g_reconnect_random, sizeof(g_reconnect_random),
+				       g_client_random, SEC_RANDOM_SIZE, security_verifier);
 			out_uint8a(s, security_verifier, sizeof(security_verifier));
 		}
 		else
@@ -511,6 +550,10 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
 
 	}
 	s_mark_end(s);
+
+	/* clear the redirect flag */
+	g_redirect = False;
+
 	sec_send(s, sec_flags);
 }
 
@@ -670,7 +713,7 @@ rdp_out_general_caps(STREAM s)
 	out_uint16_le(s, 0x200);	/* Protocol version */
 	out_uint16(s, 0);	/* Pad */
 	out_uint16(s, 0);	/* Compression types */
-	out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
+	out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 0x40d : 0);
 	/* Pad, according to T.128. 0x40d seems to 
 	   trigger
 	   the server to start sending RDP5 packets. 
@@ -924,7 +967,7 @@ rdp_send_confirm_active(void)
 		RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
 		4 /* w2k fix, sessionid */ ;
 
-	if (g_use_rdp5)
+	if (g_rdp_version >= RDP_V5)
 	{
 		caplen += RDP_CAPLEN_BMPCACHE2;
 #ifdef VBOX
@@ -957,7 +1000,7 @@ rdp_send_confirm_active(void)
 	rdp_out_general_caps(s);
 	rdp_out_bitmap_caps(s);
 	rdp_out_order_caps(s);
-	if (g_use_rdp5)
+	if (g_rdp_version >= RDP_V5)
 	{
 		rdp_out_bmpcache2_caps(s);
 #ifdef VBOX
@@ -996,7 +1039,7 @@ rdp_process_general_caps(STREAM s)
 	in_uint16_le(s, pad2octetsB);
 
 	if (!pad2octetsB)
-		g_use_rdp5 = False;
+		g_rdp_version = RDP_V4;
 }
 
 /* Process a bitmap capability set */
@@ -1078,6 +1121,9 @@ process_demand_active(STREAM s)
 	uint8 type;
 	uint16 len_src_descriptor, len_combined_caps;
 
+	/* at this point we need to ensure that we have ui created */
+	rd_create_ui();
+
 	in_uint32_le(s, g_rdp_shareid);
 	in_uint16_le(s, len_src_descriptor);
 	in_uint16_le(s, len_combined_caps);
@@ -1096,7 +1142,7 @@ process_demand_active(STREAM s)
 	rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0,
 		       g_numlock_sync ? ui_get_numlock_state(read_keyboard_state()) : 0, 0);
 
-	if (g_use_rdp5)
+	if (g_rdp_version >= RDP_V5)
 	{
 		rdp_enum_bmpcache2();
 		rdp_send_fonts(3);
@@ -1116,7 +1162,7 @@ static void
 process_colour_pointer_common(STREAM s, int bpp)
 {
 	uint16 width, height, cache_idx, masklen, datalen;
-	sint16 x, y;
+	uint16 x, y;
 	uint8 *mask;
 	uint8 *data;
 	RD_HCURSOR cursor;
@@ -1134,10 +1180,9 @@ process_colour_pointer_common(STREAM s, int bpp)
 	{
 		warning("process_colour_pointer_common: " "width %d height %d\n", width, height);
 	}
-	/* sometimes x or y is out of bounds */
-	x = MAX(x, 0);
+
+	/* keep hotspot within cursor bounding box */
 	x = MIN(x, width - 1);
-	y = MAX(y, 0);
 	y = MIN(y, height - 1);
 	cursor = ui_create_cursor(x, y, width, height, mask, data, bpp);
 	ui_set_cursor(cursor);
@@ -1405,6 +1450,7 @@ process_pdu_logon(STREAM s)
 			in_uint32_le(s, g_reconnect_logonid);
 			in_uint8a(s, g_reconnect_random, 16);
 			g_has_reconnect_random = True;
+			g_reconnect_random_ts = time(NULL);
 			DEBUG(("Saving auto-reconnect cookie, id=%u\n", g_reconnect_logonid));
 		}
 	}
@@ -1500,6 +1546,10 @@ process_data_pdu(STREAM s, uint32 * ext_disc_reason)
 			 */
 			break;
 
+		case RDP_DATA_PDU_AUTORECONNECT_STATUS:
+			warning("Automatic reconnect using cookie, failed.\n");
+			break;
+
 		default:
 			unimpl("data PDU %d\n", data_pdu_type);
 	}
@@ -1508,13 +1558,47 @@ process_data_pdu(STREAM s, uint32 * ext_disc_reason)
 
 /* Process redirect PDU from Session Directory */
 static RD_BOOL
-process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
+process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_reason */ )
 {
 	uint32 len;
+	uint16 redirect_identifier;
+
+	/* reset any previous redirection information */
+	g_redirect = True;
+	free(g_redirect_server);
+	free(g_redirect_username);
+	free(g_redirect_domain);
+	free(g_redirect_lb_info);
+	free(g_redirect_cookie);
+
+	g_redirect_server = NULL;
+	g_redirect_username = NULL;
+	g_redirect_domain = NULL;
+	g_redirect_lb_info = NULL;
+	g_redirect_cookie = NULL;
 
 	/* these 2 bytes are unknown, seem to be zeros */
 	in_uint8s(s, 2);
 
+	/* FIXME: Previous implementation only reads 4 bytes which has been working
+	   but todays spec says something different. Investigate and retest
+	   server redirection using WTS 2003 cluster.
+	 */
+
+	if (enhanced_redirect)
+	{
+		/* read identifier */
+		in_uint16_le(s, redirect_identifier);
+		if (redirect_identifier != 0x0400)
+			error("Protocol error in server redirection, unexpected data.");
+
+		/* FIXME: skip total length */
+		in_uint8s(s, 2);
+
+		/* read session_id */
+		in_uint32_le(s, g_redirect_session_id);
+	}
+
 	/* read connection flags */
 	in_uint32_le(s, g_redirect_flags);
 
@@ -1524,29 +1608,22 @@ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
 		in_uint32_le(s, len);
 
 		/* read ip string */
-		rdp_in_unistr(s, g_redirect_server, sizeof(g_redirect_server), len);
+		rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len);
 	}
 
-	if (g_redirect_flags & PDU_REDIRECT_HAS_COOKIE)
+	if (g_redirect_flags & PDU_REDIRECT_HAS_LOAD_BALANCE_INFO)
 	{
-		/* read length of cookie string */
-		in_uint32_le(s, len);
+		/* read length of load balance info blob */
+		in_uint32_le(s, g_redirect_lb_info_len);
 
-		/* read cookie string (plain ASCII) */
-		if (len > sizeof(g_redirect_cookie) - 1)
-		{
-			uint32 rem = len - (sizeof(g_redirect_cookie) - 1);
-			len = sizeof(g_redirect_cookie) - 1;
+		/* reallocate a loadbalance info blob */
+		if (g_redirect_lb_info != NULL)
+			free(g_redirect_lb_info);
 
-			warning("Unexpectedly large redirection cookie\n");
-			in_uint8a(s, g_redirect_cookie, len);
-			in_uint8s(s, rem);
-		}
-		else
-		{
-			in_uint8a(s, g_redirect_cookie, len);
-		}
-		g_redirect_cookie[len] = 0;
+		g_redirect_lb_info = xmalloc(g_redirect_lb_info_len);
+
+		/* read load balance info blob */
+		in_uint8p(s, g_redirect_lb_info, g_redirect_lb_info_len);
 	}
 
 	if (g_redirect_flags & PDU_REDIRECT_HAS_USERNAME)
@@ -1555,8 +1632,7 @@ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
 		in_uint32_le(s, len);
 
 		/* read username string */
-		g_redirect_username = (char *) xmalloc(len + 1);
-		rdp_in_unistr(s, g_redirect_username, strlen(g_redirect_username), len);
+		rdp_in_unistr(s, len, &g_redirect_username, &g_redirect_username_len);
 	}
 
 	if (g_redirect_flags & PDU_REDIRECT_HAS_DOMAIN)
@@ -1565,16 +1641,25 @@ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
 		in_uint32_le(s, len);
 
 		/* read domain string */
-		rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len);
+		rdp_in_unistr(s, len, &g_redirect_domain, &g_redirect_domain_len);
 	}
 
 	if (g_redirect_flags & PDU_REDIRECT_HAS_PASSWORD)
 	{
-		/* read length of password string */
-		in_uint32_le(s, len);
+		/* the information in this blob is either a password or a cookie that
+		   should be passed though as blob and not parsed as a unicode string */
+
+		/* read blob length */
+		in_uint32_le(s, g_redirect_cookie_len);
 
-		/* read password string */
-		rdp_in_unistr(s, g_redirect_password, sizeof(g_redirect_password), len);
+		/* reallocate cookie blob */
+		if (g_redirect_cookie != NULL)
+			free(g_redirect_cookie);
+
+		g_redirect_cookie = xmalloc(g_redirect_cookie_len);
+
+		/* read cookie as is */
+		in_uint8p(s, g_redirect_cookie, g_redirect_cookie_len);
 	}
 
 	if (g_redirect_flags & PDU_REDIRECT_DONT_STORE_USERNAME)
@@ -1589,12 +1674,24 @@ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
 
 	if (g_redirect_flags & PDU_REDIRECT_INFORMATIONAL)
 	{
-		warning("PDU_REDIRECT_INFORMATIONAL set\n");
+		/* By spec this is only for information and doesn't mean that an actual
+		   redirect should be performed. How it should be used is not mentioned. */
+		g_redirect = False;
 	}
 
 	if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_FQDN)
 	{
-		warning("PDU_REDIRECT_HAS_TARGET_FQDN set\n");
+		in_uint32_le(s, len);
+
+		/* Let target fqdn replace target ip address */
+		if (g_redirect_server)
+		{
+			free(g_redirect_server);
+			g_redirect_server = NULL;
+		}
+
+		/* read fqdn string */
+		rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len);
 	}
 
 	if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_NETBIOS)
@@ -1607,8 +1704,6 @@ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
 		warning("PDU_REDIRECT_HAS_TARGET_IP_ARRAY set\n");
 	}
 
-	g_redirect = True;
-
 	return True;
 }
 
@@ -1618,7 +1713,7 @@ rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
 {
 	while (rdp_loop(deactivated, ext_disc_reason))
 	{
-		if (g_pending_resize)
+		if (g_pending_resize || g_redirect)
 		{
 			return;
 		}
@@ -1649,9 +1744,17 @@ rdp_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
 				*deactivated = True;
 				break;
 			case RDP_PDU_REDIRECT:
-				return process_redirect_pdu(s);
+				return process_redirect_pdu(s, False);
+				break;
+			case RDP_PDU_ENHANCED_REDIRECT:
+				return process_redirect_pdu(s, True);
 				break;
 			case RDP_PDU_DATA:
+				/* If we got a data PDU, we don't need to keep the password in memory
+				   anymore and therefor we should clear it for security reasons. */
+				if (g_password[0] != '\0')
+					memset(g_password, 0, sizeof(g_password));
+
 				process_data_pdu(s, ext_disc_reason);
 				break;
 			case 0:
@@ -1669,10 +1772,26 @@ RD_BOOL
 rdp_connect(char *server, uint32 flags, char *domain, char *password,
 	    char *command, char *directory, RD_BOOL reconnect)
 {
-	if (!sec_connect(server, g_username, reconnect))
+	RD_BOOL deactivated = False;
+	uint32 ext_disc_reason = 0;
+
+	if (!sec_connect(server, g_username, domain, password, reconnect))
 		return False;
 
 	rdp_send_logon_info(flags, domain, g_username, password, command, directory);
+
+	/* run RDP loop until first licence demand active PDU */
+	while (!g_rdp_shareid)
+	{
+		if (g_network_error)
+			return False;
+
+		if (!rdp_loop(&deactivated, &ext_disc_reason))
+			return False;
+
+		if (g_redirect)
+			return True;
+	}
 	return True;
 }
 
diff --git a/src/VBox/RDP/client/rdp5.c b/src/VBox/RDP/client-1.8.3/rdp5.c
similarity index 97%
rename from src/VBox/RDP/client/rdp5.c
rename to src/VBox/RDP/client-1.8.3/rdp5.c
index 28b6c39..da72706 100644
--- a/src/VBox/RDP/client/rdp5.c
+++ b/src/VBox/RDP/client-1.8.3/rdp5.c
@@ -2,7 +2,7 @@
    rdesktop: A Remote Desktop Protocol client.
    Protocol services - RDP5 short form PDU processing
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
-   Copyright (C) Erik Forsberg <forsberg at cendio.se> 2003-2008
+   Copyright 2003-2008 Erik Forsberg <forsberg at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/src/VBox/RDP/client/rdpdr.c b/src/VBox/RDP/client-1.8.3/rdpdr.c
similarity index 89%
rename from src/VBox/RDP/client/rdpdr.c
rename to src/VBox/RDP/client-1.8.3/rdpdr.c
index c1fb288..b524c08 100644
--- a/src/VBox/RDP/client/rdpdr.c
+++ b/src/VBox/RDP/client-1.8.3/rdpdr.c
@@ -2,7 +2,7 @@
    rdesktop: A Remote Desktop Protocol client.
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
    Copyright 2004-2011 Peter Astrand <astrand at cendio.se> for Cendio AB
-   Copyright 2010-2011 Henrik Andersson <hean01 at cendio.se> for Cendio AB
+   Copyright 2010-2014 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -77,11 +77,14 @@ extern FILEINFO g_fileinfo[];
 extern RD_BOOL g_notify_stamp;
 
 static VCHANNEL *rdpdr_channel;
+static uint32 g_epoch;
 
 /* If select() times out, the request for the device with handle g_min_timeout_fd is aborted */
 RD_NTHANDLE g_min_timeout_fd;
 uint32 g_num_devices;
 
+uint32 g_client_id;
+
 /* Table with information about rdpdr devices */
 RDPDR_DEVICE g_rdpdr_device[RDPDR_MAX_DEVICES];
 char *g_rdpdr_clientname = NULL;
@@ -195,25 +198,25 @@ add_async_iorequest(uint32 device, uint32 file, uint32 id, uint32 major, uint32
 }
 
 static void
-rdpdr_send_connect(void)
+rdpdr_send_client_announce_reply(void)
 {
-	uint8 magic[4] = "rDCC";
+	/* DR_CORE_CLIENT_ANNOUNCE_RSP */
 	STREAM s;
-
 	s = channel_init(rdpdr_channel, 12);
-	out_uint8a(s, magic, 4);
-	out_uint16_le(s, 1);	/* unknown */
-	out_uint16_le(s, 5);
-	out_uint32_be(s, 0x815ed39d);	/* IP address (use 127.0.0.1) 0x815ed39d */
+	out_uint16_le(s, RDPDR_CTYP_CORE);
+	out_uint16_le(s, PAKID_CORE_CLIENTID_CONFIRM);
+	out_uint16_le(s, 1);	/* VersionMajor, MUST be set to 0x1 */
+	out_uint16_le(s, 5);	/* VersionMinor */
+	out_uint32_be(s, g_client_id);	/* ClientID */
 	s_mark_end(s);
 	channel_send(s, rdpdr_channel);
 }
 
 
 static void
-rdpdr_send_name(void)
+rdpdr_send_client_name_request(void)
 {
-	uint8 magic[4] = "rDNC";
+	/* DR_CORE_CLIENT_NAME_REQ */
 	STREAM s;
 	uint32 hostlen;
 
@@ -224,11 +227,11 @@ rdpdr_send_name(void)
 	hostlen = (strlen(g_rdpdr_clientname) + 1) * 2;
 
 	s = channel_init(rdpdr_channel, 16 + hostlen);
-	out_uint8a(s, magic, 4);
-	out_uint16_le(s, 0x63);	/* unknown */
-	out_uint16_le(s, 0x72);
-	out_uint32(s, 0);
-	out_uint32_le(s, hostlen);
+	out_uint16_le(s, RDPDR_CTYP_CORE);
+	out_uint16_le(s, PAKID_CORE_CLIENT_NAME);
+	out_uint32_le(s, 1);	/* UnicodeFlag */
+	out_uint32_le(s, 0);	/* CodePage */
+	out_uint32_le(s, hostlen);	/* ComputerNameLen */
 	rdp_out_unistr(s, g_rdpdr_clientname, hostlen - 2);
 	s_mark_end(s);
 	channel_send(s, rdpdr_channel);
@@ -263,17 +266,18 @@ announcedata_size()
 }
 
 static void
-rdpdr_send_available(void)
+rdpdr_send_client_device_list_announce(void)
 {
-
-	uint8 magic[4] = "rDAD";
+	/* DR_CORE_CLIENT_ANNOUNCE_RSP */
 	uint32 driverlen, printerlen, bloblen;
 	int i;
 	STREAM s;
 	PRINTER *printerinfo;
 
 	s = channel_init(rdpdr_channel, announcedata_size());
-	out_uint8a(s, magic, 4);
+	out_uint16_le(s, RDPDR_CTYP_CORE);
+	out_uint16_le(s, PAKID_CORE_DEVICE_LIST_ANNOUNCE);
+
 	out_uint32_le(s, g_num_devices);
 
 	for (i = 0; i < g_num_devices; i++)
@@ -310,13 +314,6 @@ rdpdr_send_available(void)
 				out_uint32(s, 0);
 		}
 	}
-#if 0
-	out_uint32_le(s, 0x20);	/* Device type 0x20 - smart card */
-	out_uint32_le(s, 0);
-	out_uint8p(s, "SCARD", 5);
-	out_uint8s(s, 3);
-	out_uint32(s, 0);
-#endif
 
 	s_mark_end(s);
 	channel_send(s, rdpdr_channel);
@@ -326,14 +323,14 @@ void
 rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer,
 		      uint32 length)
 {
-	uint8 magic[4] = "rDCI";
 	STREAM s;
 
 #ifdef WITH_SCARD
 	scard_lock(SCARD_LOCK_RDPDR);
 #endif
 	s = channel_init(rdpdr_channel, 20 + length);
-	out_uint8a(s, magic, 4);
+	out_uint16_le(s, RDPDR_CTYP_CORE);
+	out_uint16_le(s, PAKID_CORE_DEVICE_IOCOMPLETION);
 	out_uint32_le(s, device);
 	out_uint32_le(s, id);
 	out_uint32_le(s, status);
@@ -371,7 +368,9 @@ rdpdr_process_irp(STREAM s)
 		error_mode,
 		share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0;
 
-	char filename[PATH_MAX];
+	char *filename;
+	uint32 filename_len;
+
 	uint8 *buffer, *pst_buf;
 	struct stream out;
 	DEVICE_FNS *fns;
@@ -384,10 +383,20 @@ rdpdr_process_irp(STREAM s)
 	in_uint32_le(s, major);
 	in_uint32_le(s, minor);
 
+	filename = NULL;
+
 	buffer_len = 0;
 	buffer = (uint8 *) xmalloc(1024);
 	buffer[0] = 0;
 
+	if (device >= RDPDR_MAX_DEVICES)
+	{
+		error("invalid irp device 0x%lx file 0x%lx id 0x%lx major 0x%lx minor 0x%lx\n",
+		      device, file, id, major, minor);
+		xfree(buffer);
+		return;
+	}
+
 	switch (g_rdpdr_device[device].device_type)
 	{
 		case DEVICE_TYPE_SERIAL:
@@ -440,22 +449,22 @@ rdpdr_process_irp(STREAM s)
 
 			if (length && (length / 2) < 256)
 			{
-				rdp_in_unistr(s, filename, sizeof(filename), length);
-				convert_to_unix_filename(filename);
-			}
-			else
-			{
-				filename[0] = 0;
+				rdp_in_unistr(s, length, &filename, &filename_len);
+				if (filename)
+					convert_to_unix_filename(filename);
 			}
 
 			if (!fns->create)
 			{
 				status = RD_STATUS_NOT_SUPPORTED;
+				free(filename);
 				break;
 			}
 
 			status = fns->create(device, desired_access, share_mode, disposition,
 					     flags_and_attributes, filename, &result);
+
+			free(filename);
 			buffer_len = 1;
 			break;
 
@@ -633,14 +642,11 @@ rdpdr_process_irp(STREAM s)
 					in_uint8s(s, 0x17);
 					if (length && length < 2 * 255)
 					{
-						rdp_in_unistr(s, filename, sizeof(filename),
-							      length);
-						convert_to_unix_filename(filename);
-					}
-					else
-					{
-						filename[0] = 0;
+						rdp_in_unistr(s, length, &filename, &filename_len);
+						if (filename)
+							convert_to_unix_filename(filename);
 					}
+
 					out.data = out.p = buffer;
 					out.size = sizeof(buffer);
 					status = disk_query_directory(file, info_level, filename,
@@ -648,6 +654,8 @@ rdpdr_process_irp(STREAM s)
 					result = buffer_len = out.p - out.data;
 					if (!buffer_len)
 						buffer_len++;
+
+					free(filename);
 					break;
 
 				case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
@@ -697,7 +705,7 @@ rdpdr_process_irp(STREAM s)
 			out.size = sizeof(buffer);
 
 #ifdef WITH_SCARD
-			scardSetInfo(device, id, bytes_out + 0x14);
+			scardSetInfo(g_epoch, device, id, bytes_out + 0x14);
 #endif
 			status = fns->device_control(file, request, s, &out);
 			result = buffer_len = out.p - out.data;
@@ -752,13 +760,13 @@ rdpdr_process_irp(STREAM s)
 }
 
 static void
-rdpdr_send_clientcapability(void)
+rdpdr_send_client_capability_response(void)
 {
-	uint8 magic[4] = "rDPC";
+	/* DR_CORE_CAPABILITY_RSP */
 	STREAM s;
-
 	s = channel_init(rdpdr_channel, 0x50);
-	out_uint8a(s, magic, 4);
+	out_uint16_le(s, RDPDR_CTYP_CORE);
+	out_uint16_le(s, PAKID_CORE_CLIENT_CAPABILITY);
 	out_uint32_le(s, 5);	/* count */
 	out_uint16_le(s, 1);	/* first */
 	out_uint16_le(s, 0x28);	/* length */
@@ -795,58 +803,70 @@ static void
 rdpdr_process(STREAM s)
 {
 	uint32 handle;
-	uint8 *magic;
+	uint16 vmin;
+	uint16 component;
+	uint16 pakid;
 
 #if WITH_DEBUG_RDP5
 	printf("--- rdpdr_process ---\n");
 	hexdump(s->p, s->end - s->p);
 #endif
-	in_uint8p(s, magic, 4);
 
-	if ((magic[0] == 'r') && (magic[1] == 'D'))
+	in_uint16(s, component);
+	in_uint16(s, pakid);
+
+	if (component == RDPDR_CTYP_CORE)
 	{
-		if ((magic[2] == 'R') && (magic[3] == 'I'))
-		{
-			rdpdr_process_irp(s);
-			return;
-		}
-		if ((magic[2] == 'n') && (magic[3] == 'I'))
-		{
-			rdpdr_send_connect();
-			rdpdr_send_name();
-			return;
-		}
-		if ((magic[2] == 'C') && (magic[3] == 'C'))
+		switch (pakid)
 		{
-			/* connect from server */
-			rdpdr_send_clientcapability();
-			rdpdr_send_available();
-			return;
-		}
-		if ((magic[2] == 'r') && (magic[3] == 'd'))
-		{
-			/* connect to a specific resource */
-			in_uint32(s, handle);
+			case PAKID_CORE_DEVICE_IOREQUEST:
+				rdpdr_process_irp(s);
+				break;
+
+			case PAKID_CORE_SERVER_ANNOUNCE:
+				/* DR_CORE_SERVER_ANNOUNCE_REQ */
+				in_uint8s(s, 2);	/* skip versionMajor */
+				in_uint16_le(s, vmin);	/* VersionMinor */
+				in_uint32_le(s, g_client_id);	/* ClientID */
+
+				/* The RDP client is responsibility to provide a random client id
+				   if server version is < 12 */
+				if (vmin < 0x000c)
+					g_client_id = 0x815ed39d;	/* IP address (use 127.0.0.1) 0x815ed39d */
+				g_epoch++;
+
+				rdpdr_send_client_announce_reply();
+				rdpdr_send_client_name_request();
+				break;
+
+			case PAKID_CORE_CLIENTID_CONFIRM:
+				rdpdr_send_client_device_list_announce();
+				break;
+
+			case PAKID_CORE_DEVICE_REPLY:
+				in_uint32(s, handle);
 #if WITH_DEBUG_RDP5
-			DEBUG(("RDPDR: Server connected to resource %d\n", handle));
+				DEBUG(("RDPDR: Server connected to resource %d\n", handle));
 #endif
-			return;
-		}
-		if ((magic[2] == 'P') && (magic[3] == 'S'))
-		{
-			/* server capability */
-			return;
+				break;
+
+			case PAKID_CORE_SERVER_CAPABILITY:
+				rdpdr_send_client_capability_response();
+				break;
+
+			default:
+				unimpl("RDPDR pakid 0x%x of component 0x%x\n", pakid, component);
+				break;
+
 		}
 	}
-	if ((magic[0] == 'R') && (magic[1] == 'P'))
+	else if (component == RDPDR_CTYP_PRN)
 	{
-		if ((magic[2] == 'C') && (magic[3] == 'P'))
-		{
+		if (pakid == PAKID_PRN_CACHE_DATA)
 			printercache_process(s);
-			return;
-		}
 	}
-	unimpl("RDPDR packet type %c%c%c%c\n", magic[0], magic[1], magic[2], magic[3]);
+	else
+		unimpl("RDPDR component 0x%x\n", component);
 }
 
 RD_BOOL
diff --git a/src/VBox/RDP/client/rdpsnd.c b/src/VBox/RDP/client-1.8.3/rdpsnd.c
similarity index 98%
rename from src/VBox/RDP/client/rdpsnd.c
rename to src/VBox/RDP/client-1.8.3/rdpsnd.c
index 758b570..a39432f 100644
--- a/src/VBox/RDP/client/rdpsnd.c
+++ b/src/VBox/RDP/client-1.8.3/rdpsnd.c
@@ -49,11 +49,18 @@
 #define RDPSND_REC_DATA			42
 #define RDPSND_REC_SET_VOLUME	43
 
+/* Special flag for RDPSND recording extension,
+   not defined in MS specs.
+
+   See doc/rdpsnd-rec.txt for more information.
+*/
 #define RDPSND_FLAG_RECORD		0x00800000
 
 #define MAX_FORMATS		10
 #define MAX_QUEUE		50
 
+extern RD_BOOL g_rdpsnd;
+
 static VCHANNEL *rdpsnd_channel;
 static VCHANNEL *rdpsnddbg_channel;
 static struct audio_driver *drivers = NULL;
@@ -264,7 +271,7 @@ rdpsnd_process_negotiate(STREAM in)
 		rdpsnd_reset_state();
 	}
 
-	if (!current_driver)
+	if (!current_driver && g_rdpsnd)
 		device_available = rdpsnd_auto_select();
 
 	if (current_driver && !device_available && current_driver->wave_out_open())
@@ -310,7 +317,18 @@ rdpsnd_process_negotiate(STREAM in)
 	}
 
 	out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
-	out_uint32_le(out, 0x00800003);	/* flags */
+
+	uint32 flags = TSSNDCAPS_VOLUME;
+
+	/* if sound is enabled, set snd caps to alive to enable
+	   transmision of audio from server */
+	if (g_rdpsnd)
+	{
+		flags |= TSSNDCAPS_ALIVE;
+		flags |= RDPSND_FLAG_RECORD;
+	}
+	out_uint32_le(out, flags);	/* TSSNDCAPS flags */
+
 	out_uint32(out, 0xffffffff);	/* volume */
 	out_uint32(out, 0);	/* pitch */
 	out_uint16(out, 0);	/* UDP port */
diff --git a/src/VBox/RDP/client/rdpsnd.h b/src/VBox/RDP/client-1.8.3/rdpsnd.h
similarity index 100%
rename from src/VBox/RDP/client/rdpsnd.h
rename to src/VBox/RDP/client-1.8.3/rdpsnd.h
diff --git a/src/VBox/RDP/client/rdpsnd_alsa.c b/src/VBox/RDP/client-1.8.3/rdpsnd_alsa.c
similarity index 100%
rename from src/VBox/RDP/client/rdpsnd_alsa.c
rename to src/VBox/RDP/client-1.8.3/rdpsnd_alsa.c
diff --git a/src/VBox/RDP/client/rdpsnd_dsp.c b/src/VBox/RDP/client-1.8.3/rdpsnd_dsp.c
similarity index 99%
rename from src/VBox/RDP/client/rdpsnd_dsp.c
rename to src/VBox/RDP/client-1.8.3/rdpsnd_dsp.c
index a15ea96..d96e031 100644
--- a/src/VBox/RDP/client/rdpsnd_dsp.c
+++ b/src/VBox/RDP/client-1.8.3/rdpsnd_dsp.c
@@ -264,7 +264,7 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
 #ifdef HAVE_LIBSAMPLERATE
 	if (src_converter == NULL)
 	{
-		warning("no samplerate converter available!!\n");
+		warning("no samplerate converter available!\n");
 		return 0;
 	}
 
diff --git a/src/VBox/RDP/client/rdpsnd_dsp.h b/src/VBox/RDP/client-1.8.3/rdpsnd_dsp.h
similarity index 100%
rename from src/VBox/RDP/client/rdpsnd_dsp.h
rename to src/VBox/RDP/client-1.8.3/rdpsnd_dsp.h
diff --git a/src/VBox/RDP/client/rdpsnd_libao.c b/src/VBox/RDP/client-1.8.3/rdpsnd_libao.c
similarity index 97%
rename from src/VBox/RDP/client/rdpsnd_libao.c
rename to src/VBox/RDP/client-1.8.3/rdpsnd_libao.c
index 419b618..62f11c3 100644
--- a/src/VBox/RDP/client/rdpsnd_libao.c
+++ b/src/VBox/RDP/client-1.8.3/rdpsnd_libao.c
@@ -4,6 +4,7 @@
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
    Copyright (C) GuoJunBo <guojunbo at ict.ac.cn> 2003
    Copyright (C) Michael Gernoth <mike at zerfleddert.de> 2005-2008
+   Copyright (C) 2013 Henrik Andersson
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -80,12 +81,12 @@ libao_open(void)
 		default_driver = ao_default_driver_id();
 	}
 
+	memset(&format, 0, sizeof(format));
 	format.bits = 16;
 	format.channels = 2;
 	format.rate = 44100;
 	format.byte_format = AO_FMT_NATIVE;
 
-
 	o_device = ao_open_live(default_driver, &format, NULL);
 	if (o_device == NULL)
 	{
@@ -119,6 +120,7 @@ libao_set_format(RD_WAVEFORMATEX * pwfx)
 {
 	ao_sample_format format;
 
+	memset(&format, 0, sizeof(format));
 	format.bits = pwfx->wBitsPerSample;
 	format.channels = pwfx->nChannels;
 	format.rate = 44100;
diff --git a/src/VBox/RDP/client/rdpsnd_oss.c b/src/VBox/RDP/client-1.8.3/rdpsnd_oss.c
similarity index 100%
rename from src/VBox/RDP/client/rdpsnd_oss.c
rename to src/VBox/RDP/client-1.8.3/rdpsnd_oss.c
diff --git a/src/VBox/RDP/client/rdpsnd_sgi.c b/src/VBox/RDP/client-1.8.3/rdpsnd_sgi.c
similarity index 100%
rename from src/VBox/RDP/client/rdpsnd_sgi.c
rename to src/VBox/RDP/client-1.8.3/rdpsnd_sgi.c
diff --git a/src/VBox/RDP/client/rdpsnd_sun.c b/src/VBox/RDP/client-1.8.3/rdpsnd_sun.c
similarity index 100%
rename from src/VBox/RDP/client/rdpsnd_sun.c
rename to src/VBox/RDP/client-1.8.3/rdpsnd_sun.c
diff --git a/src/VBox/RDP/client/scancodes.h b/src/VBox/RDP/client-1.8.3/scancodes.h
similarity index 100%
rename from src/VBox/RDP/client/scancodes.h
rename to src/VBox/RDP/client-1.8.3/scancodes.h
diff --git a/src/VBox/RDP/client/scard.c b/src/VBox/RDP/client-1.8.3/scard.c
similarity index 86%
rename from src/VBox/RDP/client/scard.c
rename to src/VBox/RDP/client-1.8.3/scard.c
index 521c90c..19aa315 100644
--- a/src/VBox/RDP/client/scard.c
+++ b/src/VBox/RDP/client-1.8.3/scard.c
@@ -2,7 +2,8 @@
    rdesktop: A Remote Desktop Protocol client.
    Smart Card support
    Copyright (C) Alexi Volkov <alexi at myrealbox.com> 2006
-   Copyright 2010 Pierre Ossman <ossman at cendio.se> for Cendio AB
+   Copyright 2010-2013 Pierre Ossman <ossman at cendio.se> for Cendio AB
+   Copyright 2011-2014 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -29,6 +30,7 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <assert.h>
 #include <fcntl.h>
 #include <strings.h>
 #include <sys/types.h>
@@ -70,7 +72,7 @@
 
 static pthread_mutex_t **scard_mutex = NULL;
 
-static uint32 curDevice = 0, curId = 0, curBytesOut = 0;
+static uint32 curEpoch = 0, curDevice = 0, curId = 0, curBytesOut = 0;
 static PSCNameMapRec nameMapList = NULL;
 static int nameMapCount = 0;
 
@@ -94,11 +96,12 @@ static void *queue_handler_function(void *data);
 
 #endif /* MAKE_PROTO */
 void
-scardSetInfo(uint32 device, uint32 id, uint32 bytes_out)
+scardSetInfo(uint32 epoch, uint32 device, uint32 id, uint32 bytes_out)
 {
 	curDevice = device;
 	curId = id;
 	curBytesOut = bytes_out;
+	curEpoch = epoch;
 }
 
 #ifndef MAKE_PROTO
@@ -251,69 +254,109 @@ scard_enum_devices(uint32 * id, char *optarg)
 }
 
 #ifndef MAKE_PROTO
-/* ---------------------------------- */
+typedef struct _scard_handle_list_t
+{
+	struct _scard_handle_list_t *next;
+	/* pcsc handles is datatype long which 
+	   is arch sizedependent */
+	long handle;
+	/* rdp server handles are always 32bit */
+	uint32_t server;
+} _scard_handle_list_t;
 
-/* These two functions depend heavily on the actual implementation of the smart
- * card handle in PC/SC Lite 1.3.1. Here are the salient bits:
- *
- * From winscard.c:331, in SCardConnect:
- *         *phCard = RFCreateReaderHandle(rContext);
- *
- * RFCreateReaderHandle (readerfactory.c:1161) creates a random short (16-bit
- * integer) and makes sure it's unique. Then it adds it to
- * rContext->dwIdentity.
- *
- * From readerfactory.c:173, in RFAddReader:
- *         (sReadersContexts[dwContext])->dwIdentity =
- *               (dwContext + 1) << (sizeof(DWORD) / 2) * 8;
- *
- * dwContext must be less than PCSCLITE_MAX_READERS_CONTEXTS, which is defined
- * to be 16 in the 1.3.1 release. 
- *
- * The use of "(sizeof(DWORD) / 2) * 8" is what makes conversion necessary in
- * order to use 64-bit card handles when talking to PC/SC Lite, and 32-bit card
- * handles when talking with the server, without losing any data: a card handle
- * made by a 32-bit PC/SC Lite looks like 0x00014d32, where the 4d32 is the
- * random 16 bits, 01 is the reader context index + 1, and it's left-shifted by 
- * 16 bits (sizeof(DWORD) == 4, divided by 2 is 2, times 8 is 16.) But a 64-bit
- * PC/SC Lite makes a card handle that looks like 0x0000000100004d32. The
- * reader context index+1 is left-shifted 32 bits because sizeof(DWORD) is 8,
- * not 4. This means the handle won't fit in 32 bits. (The multiplication by 8
- * is because sizeofs are in bytes, but saying how many places to left-shift is
- * speaking in bits.)
- *
- * So then. Maximum value of dwContext+1 is 17; we'll say this fits in a byte
- * to be loose and have plenty of room. This is then left-shifted by
- * sizeof(DWORD) / 2 * 8 - which in this file is sizeof(MYPCSC_DWORD) / 2 * 8.
- *
- * At any rate, if we take the handle as passed from PC/SC Lite, right-shift by
- * sizeof(MYPCSC_DWORD) / 2, left-shift by sizeof(SERVER_DWORD) / 2, and add
- * the lower two bytes of the value (the random number), we can fit all the
- * information into 32 bits without losing any. Of course, any time we want to
- * hand that back to PC/SC Lite, we'll have to expand it again. (And if
- * sizeof(MYPCSC_DWORD) == sizeof(SERVER_DWORD), we're essentially doing
- * nothing, which will not break anything.)
- *
- *
- * - jared.jennings at eglin.af.mil, 2 Aug 2006
- */
+static uint32_t g_scard_handle_counter = 0;
+static _scard_handle_list_t *g_scard_handle_list = NULL;
 
+static void _scard_handle_list_add(long handle);
+static void _scard_handle_list_remove(long handle);
+static uint32_t _scard_handle_list_get_server_handle(long handle);
+static long _scard_handle_list_get_pcsc_handle(uint32_t server);
 
-static MYPCSC_SCARDHANDLE
-scHandleToMyPCSC(SERVER_SCARDHANDLE server)
+void
+_scard_handle_list_add(long handle)
 {
-	return (((MYPCSC_SCARDHANDLE) server >> (sizeof(SERVER_DWORD) * 8 / 2) & 0xffff)
-		<< (sizeof(MYPCSC_DWORD) * 8 / 2)) + (server & 0xffff);
+	_scard_handle_list_t *list = g_scard_handle_list;
+	/* we dont care of order of list so to simplify the add 
+	   we add new items to front of list */
+	_scard_handle_list_t *item = xmalloc(sizeof(_scard_handle_list_t));
+	item->next = list;
+	item->handle = handle;
+
+	/* lookup first unused handle id */
+	int overlap = 0;
+	if (g_scard_handle_counter == 0)
+		g_scard_handle_counter++;
+
+	while (_scard_handle_list_get_pcsc_handle(g_scard_handle_counter))
+	{
+		g_scard_handle_counter++;
+
+		if (g_scard_handle_counter == 0 && overlap)
+			assert(!"broken smartcard client software, handles are not freed and there is no more handles left to allocate.");
+
+		if (g_scard_handle_counter == 0)
+			overlap = g_scard_handle_counter = 1;
+
+	}
+
+	item->server = g_scard_handle_counter;
+	g_scard_handle_list = item;
 }
 
-static SERVER_SCARDHANDLE
-scHandleToServer(MYPCSC_SCARDHANDLE mypcsc)
+void
+_scard_handle_list_remove(long handle)
 {
-	return ((mypcsc >> (sizeof(MYPCSC_DWORD) * 8 / 2) & 0xffff)
-		<< (sizeof(SERVER_DWORD) * 8 / 2)) + (mypcsc & 0xffff);
+	_scard_handle_list_t *item, *list, *prev_item;
+	prev_item = NULL;
+	item = list = g_scard_handle_list;
+
+	while (item)
+	{
+		if (item->handle == handle)
+		{
+			/* unlink from list */
+			if (prev_item)
+				prev_item->next = item->next;
+			else
+				g_scard_handle_list = item->next;
+
+			xfree(item);
+			break;
+		}
+
+		/* store previous item for relinking */
+		prev_item = item;
+		item = item->next;
+	}
 }
 
-/* ---------------------------------- */
+uint32_t
+_scard_handle_list_get_server_handle(long handle)
+{
+	_scard_handle_list_t *item;
+	item = g_scard_handle_list;
+	while (item)
+	{
+		if (item->handle == handle)
+			return item->server;
+		item = item->next;
+	}
+	return 0;
+}
+
+long
+_scard_handle_list_get_pcsc_handle(uint32_t server)
+{
+	_scard_handle_list_t *item;
+	item = g_scard_handle_list;
+	while (item)
+	{
+		if (item->server == server)
+			return item->handle;
+		item = item->next;
+	}
+	return 0;
+}
 
 static void *
 SC_xmalloc(PMEM_HANDLE * memHandle, unsigned int size)
@@ -623,11 +666,22 @@ static MYPCSC_DWORD
 TS_SCardEstablishContext(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
-	MYPCSC_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
+	SERVER_SCARDCONTEXT hContext;
+
 	/* code segment  */
 
 	DEBUG_SCARD(("SCARD: SCardEstablishContext()\n"));
-	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &myHContext);
+
+	hContext = 0;
+	if (myHContext)
+	{
+		_scard_handle_list_add(myHContext);
+		hContext = _scard_handle_list_get_server_handle(myHContext);
+	}
+
+
 	if (rv)
 	{
 		DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n",
@@ -635,14 +689,18 @@ TS_SCardEstablishContext(STREAM in, STREAM out)
 	}
 	else
 	{
-		DEBUG_SCARD(("SCARD: -> Success (context: 0x%08lx)\n", hContext));
+		DEBUG_SCARD(("SCARD: -> Success (context: 0x%08x [0x%lx])\n", hContext,
+			     myHContext));
 	}
 
+
+
 	out_uint32_le(out, 0x00000004);
-	out_uint32_le(out, (SERVER_DWORD) hContext);	/* must not be 0 (Seems to be pointer), don't know what is this (I use hContext as value) */
+	out_uint32_le(out, hContext);	/* must not be 0 (Seems to be pointer), don't know what is this (I use hContext as value) */
 	/* i hope it's not a pointer because i just downcasted it - jlj */
 	out_uint32_le(out, 0x00000004);
-	out_uint32_le(out, (SERVER_DWORD) hContext);
+	out_uint32_le(out, hContext);
+	outForceAlignment(out, 8);
 	return rv;
 }
 
@@ -650,12 +708,19 @@ static MYPCSC_DWORD
 TS_SCardReleaseContext(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
+	MYPCSC_SCARDCONTEXT myHContext;
 	SERVER_SCARDCONTEXT hContext;
 
 	in->p += 0x1C;
 	in_uint32_le(in, hContext);
-	DEBUG_SCARD(("SCARD: SCardReleaseContext(context: 0x%08x)\n", (unsigned) hContext));
-	rv = SCardReleaseContext((MYPCSC_SCARDCONTEXT) hContext);
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+
+	DEBUG_SCARD(("SCARD: SCardReleaseContext(context: 0x%08x [0x%lx])\n", (unsigned) hContext,
+		     myHContext));
+
+	rv = SCardReleaseContext(myHContext);
+
+	_scard_handle_list_remove(myHContext);
 
 	if (rv)
 	{
@@ -667,6 +732,7 @@ TS_SCardReleaseContext(STREAM in, STREAM out)
 		DEBUG_SCARD(("SCARD: -> Success\n"));
 	}
 
+	outForceAlignment(out, 8);
 	return rv;
 }
 
@@ -675,20 +741,25 @@ TS_SCardIsValidContext(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
 	char *readers;
 	DWORD readerCount = 1024;
 	PMEM_HANDLE lcHandle = NULL;
 
 	in->p += 0x1C;
 	in_uint32_le(in, hContext);
-	DEBUG_SCARD(("SCARD: SCardIsValidContext(context: 0x%08x)\n", (unsigned) hContext));
+
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+
+	DEBUG_SCARD(("SCARD: SCardIsValidContext(context: 0x%08x [0x%lx])\n",
+		     (unsigned) hContext, myHContext));
 	/* There is no realization of SCardIsValidContext in PC/SC Lite so we call SCardListReaders */
 
 	readers = SC_xmalloc(&lcHandle, 1024);
 	if (!readers)
 		return SC_returnNoMemoryError(&lcHandle, in, out);
 
-	rv = SCardListReaders((MYPCSC_SCARDCONTEXT) hContext, NULL, readers, &readerCount);
+	rv = SCardListReaders(myHContext, NULL, readers, &readerCount);
 
 	if (rv)
 	{
@@ -713,6 +784,7 @@ TS_SCardListReaders(STREAM in, STREAM out, RD_BOOL wide)
 #define readerArraySize 1024
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
 	SERVER_DWORD dataLength;
 	MYPCSC_DWORD cchReaders = readerArraySize;
 	unsigned char *plen1, *plen2, *pend;
@@ -721,7 +793,9 @@ TS_SCardListReaders(STREAM in, STREAM out, RD_BOOL wide)
 
 	in->p += 0x2C;
 	in_uint32_le(in, hContext);
-	DEBUG_SCARD(("SCARD: SCardListReaders(context: 0x%08x)\n", (unsigned) hContext));
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+	DEBUG_SCARD(("SCARD: SCardListReaders(context: 0x%08x [0x%lx])\n",
+		     (unsigned) hContext, myHContext));
 	plen1 = out->p;
 	out_uint32_le(out, 0x00000000);	/* Temp value for data length as 0x0 */
 	out_uint32_le(out, 0x01760650);
@@ -736,7 +810,7 @@ TS_SCardListReaders(STREAM in, STREAM out, RD_BOOL wide)
 
 	readers[0] = '\0';
 	readers[1] = '\0';
-	rv = SCardListReaders((MYPCSC_SCARDCONTEXT) hContext, NULL, readers, &cchReaders);
+	rv = SCardListReaders(myHContext, NULL, readers, &cchReaders);
 	cur = readers;
 	if (rv != SCARD_S_SUCCESS)
 	{
@@ -789,7 +863,8 @@ static MYPCSC_DWORD
 TS_SCardConnect(STREAM in, STREAM out, RD_BOOL wide)
 {
 	MYPCSC_DWORD rv;
-	SCARDCONTEXT hContext;
+	SCARDCONTEXT myHContext;
+	SERVER_SCARDCONTEXT hContext;
 	char *szReader;
 	SERVER_DWORD dwShareMode;
 	SERVER_DWORD dwPreferredProtocol;
@@ -805,10 +880,21 @@ TS_SCardConnect(STREAM in, STREAM out, RD_BOOL wide)
 	inReaderName(&lcHandle, in, &szReader, wide);
 	in->p += 0x04;
 	in_uint32_le(in, hContext);
-	DEBUG_SCARD(("SCARD: SCardConnect(context: 0x%08x, share: 0x%08x, proto: 0x%08x, reader: \"%s\")\n", (unsigned) hContext, (unsigned) dwShareMode, (unsigned) dwPreferredProtocol, szReader ? szReader : "NULL"));
-	rv = SCardConnect(hContext, szReader, (MYPCSC_DWORD) dwShareMode,
+
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+
+	DEBUG_SCARD(("SCARD: SCardConnect(context: 0x%08x [0x%lx], share: 0x%08x, proto: 0x%08x, reader: \"%s\")\n", (unsigned) hContext, myHContext, (unsigned) dwShareMode, (unsigned) dwPreferredProtocol, szReader ? szReader : "NULL"));
+
+	rv = SCardConnect(myHContext, szReader, (MYPCSC_DWORD) dwShareMode,
 			  (MYPCSC_DWORD) dwPreferredProtocol, &myHCard, &dwActiveProtocol);
-	hCard = scHandleToServer(myHCard);
+
+	hCard = 0;
+	if (myHCard)
+	{
+		_scard_handle_list_add(myHCard);
+		hCard = _scard_handle_list_get_server_handle(myHCard);
+	}
+
 	if (rv != SCARD_S_SUCCESS)
 	{
 		DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n",
@@ -817,8 +903,8 @@ TS_SCardConnect(STREAM in, STREAM out, RD_BOOL wide)
 	else
 	{
 		char *szVendor = getVendor(szReader);
-		DEBUG_SCARD(("SCARD: -> Success (hcard: 0x%08x [0x%08lx])\n",
-			     (unsigned) hCard, (unsigned long) myHCard));
+		DEBUG_SCARD(("SCARD: -> Success (hcard: 0x%08x [0x%lx])\n",
+			     (unsigned) hCard, myHCard));
 		if (szVendor && (strlen(szVendor) > 0))
 		{
 			DEBUG_SCARD(("SCARD: Set Attribute ATTR_VENDOR_NAME\n"));
@@ -860,7 +946,7 @@ static MYPCSC_DWORD
 TS_SCardReconnect(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
-	SCARDCONTEXT hContext;
+	SERVER_SCARDCONTEXT hContext;
 	SERVER_SCARDHANDLE hCard;
 	MYPCSC_SCARDHANDLE myHCard;
 	SERVER_DWORD dwShareMode;
@@ -876,8 +962,10 @@ TS_SCardReconnect(STREAM in, STREAM out)
 	in_uint32_le(in, hContext);
 	in->p += 0x04;
 	in_uint32_le(in, hCard);
-	myHCard = scHandleToMyPCSC(hCard);
-	DEBUG_SCARD(("SCARD: SCardReconnect(context: 0x%08x, hcard: 0x%08x [0x%08lx], share: 0x%08x, proto: 0x%08x, init: 0x%08x)\n", (unsigned) hContext, (unsigned) hCard, (unsigned long) myHCard, (unsigned) dwShareMode, (unsigned) dwPreferredProtocol, (unsigned) dwInitialization));
+
+
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
+	DEBUG_SCARD(("SCARD: SCardReconnect(context: 0x%08x, hcard: 0x%08x [%lx], share: 0x%08x, proto: 0x%08x, init: 0x%08x)\n", (unsigned) hContext, (unsigned) hCard, myHCard, (unsigned) dwShareMode, (unsigned) dwPreferredProtocol, (unsigned) dwInitialization));
 	rv = SCardReconnect(myHCard, (MYPCSC_DWORD) dwShareMode, (MYPCSC_DWORD) dwPreferredProtocol,
 			    (MYPCSC_DWORD) dwInitialization, &dwActiveProtocol);
 	if (rv != SCARD_S_SUCCESS)
@@ -890,8 +978,8 @@ TS_SCardReconnect(STREAM in, STREAM out)
 		DEBUG_SCARD(("SCARD: -> Success (proto: 0x%08x)\n", (unsigned) dwActiveProtocol));
 	}
 
-	outForceAlignment(out, 8);
 	out_uint32_le(out, (SERVER_DWORD) dwActiveProtocol);
+	outForceAlignment(out, 8);
 	return rv;
 }
 
@@ -900,6 +988,7 @@ TS_SCardDisconnect(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
 	SERVER_SCARDHANDLE hCard;
 	MYPCSC_SCARDHANDLE myHCard;
 	SERVER_DWORD dwDisposition;
@@ -911,7 +1000,10 @@ TS_SCardDisconnect(STREAM in, STREAM out)
 	in->p += 0x04;
 	in_uint32_le(in, hCard);
 
-	DEBUG_SCARD(("SCARD: SCardDisconnect(context: 0x%08x, hcard: 0x%08x, disposition: 0x%08x)\n", (unsigned) hContext, (unsigned) hCard, (unsigned) dwDisposition));
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
+
+	DEBUG_SCARD(("SCARD: SCardDisconnect(context: 0x%08x [0x%lx], hcard: 0x%08x [0x%lx], disposition: 0x%08x)\n", (unsigned) hContext, myHContext, (unsigned) hCard, myHCard, (unsigned) dwDisposition));
 
 	pthread_mutex_lock(&hcardAccess);
 	PSCHCardRec hcard = hcardFirst;
@@ -932,9 +1024,10 @@ TS_SCardDisconnect(STREAM in, STREAM out)
 	}
 	pthread_mutex_unlock(&hcardAccess);
 
-	myHCard = scHandleToMyPCSC(hCard);
 	rv = SCardDisconnect(myHCard, (MYPCSC_DWORD) dwDisposition);
 
+	_scard_handle_list_remove(myHCard);
+
 	if (rv != SCARD_S_SUCCESS)
 	{
 		DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n",
@@ -1023,8 +1116,10 @@ TS_SCardGetStatusChange(STREAM in, STREAM out, RD_BOOL wide)
 {
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
 	SERVER_DWORD dwTimeout;
 	SERVER_DWORD dwCount;
+	SERVER_DWORD dwPointerId;
 	SERVER_LPSCARD_READERSTATE_A rsArray, cur;
 	MYPCSC_LPSCARD_READERSTATE_A myRsArray;
 	long i;
@@ -1037,8 +1132,9 @@ TS_SCardGetStatusChange(STREAM in, STREAM out, RD_BOOL wide)
 	in_uint32_le(in, hContext);
 	in->p += 0x04;
 
-	DEBUG_SCARD(("SCARD: SCardGetStatusChange(context: 0x%08x, timeout: 0x%08x, count: %d)\n",
-		     (unsigned) hContext, (unsigned) dwTimeout, (int) dwCount));
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+
+	DEBUG_SCARD(("SCARD: SCardGetStatusChange(context: 0x%08x [0x%lx], timeout: 0x%08x, count: %d)\n", (unsigned) hContext, myHContext, (unsigned) dwTimeout, (int) dwCount));
 
 	if (dwCount > 0)
 	{
@@ -1046,35 +1142,35 @@ TS_SCardGetStatusChange(STREAM in, STREAM out, RD_BOOL wide)
 		if (!rsArray)
 			return SC_returnNoMemoryError(&lcHandle, in, out);
 		memset(rsArray, 0, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
-		/* skip two pointers at beginning of struct */
-		for (i = 0, cur = (SERVER_LPSCARD_READERSTATE_A) ((unsigned char **) rsArray + 2);
-		     i < dwCount; i++, cur++)
+		for (i = 0, cur = rsArray; i < dwCount; i++, cur++)
 		{
-			in->p += 0x04;
-			in_uint8a(in, cur, SERVER_SCARDSTATESIZE);
+			in_uint32_le(in, dwPointerId);
+			cur->szReader = (char *) (intptr_t) dwPointerId;
+			in_uint32_le(in, cur->dwCurrentState);
+			in_uint32_le(in, cur->dwEventState);
+			in_uint32_le(in, cur->cbAtr);
+			in_uint8a(in, cur->rgbAtr, sizeof(cur->rgbAtr));
 		}
 
 		for (i = 0, cur = rsArray; i < dwCount; i++, cur++)
 		{
-			SERVER_DWORD dataLength;
-
-			/* Do endian swaps... */
-			cur->dwCurrentState = swap32(cur->dwCurrentState);
-			cur->dwEventState = swap32(cur->dwEventState);
-			cur->cbAtr = swap32(cur->cbAtr);
+			if (cur->szReader != NULL)
+			{
+				SERVER_DWORD dataLength;
 
-			in->p += 0x08;
-			in_uint32_le(in, dataLength);
-			inRepos(in,
-				inString(&lcHandle, in, (char **) &(cur->szReader), dataLength,
-					 wide));
+				in->p += 0x08;
+				in_uint32_le(in, dataLength);
+				inRepos(in,
+					inString(&lcHandle, in, (char **) &(cur->szReader),
+						 dataLength, wide));
 
-			if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0)
-				cur->dwCurrentState |= SCARD_STATE_IGNORE;
+				if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0)
+					cur->dwCurrentState |= SCARD_STATE_IGNORE;
+			}
 
 			DEBUG_SCARD(("SCARD:    \"%s\"\n", cur->szReader ? cur->szReader : "NULL"));
-			DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n",
-				     (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
+			DEBUG_SCARD(("SCARD:        user: %p, state: 0x%08x, event: 0x%08x\n",
+				     cur->pvUserData, (unsigned) cur->dwCurrentState,
 				     (unsigned) cur->dwEventState));
 		}
 	}
@@ -1084,12 +1180,17 @@ TS_SCardGetStatusChange(STREAM in, STREAM out, RD_BOOL wide)
 	}
 
 	myRsArray = SC_xmalloc(&lcHandle, dwCount * sizeof(MYPCSC_SCARD_READERSTATE_A));
-	if (!rsArray)
+	if (!myRsArray)
 		return SC_returnNoMemoryError(&lcHandle, in, out);
 	memset(myRsArray, 0, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
 	copyReaderState_ServerToMyPCSC(rsArray, myRsArray, (SERVER_DWORD) dwCount);
 
-	rv = SCardGetStatusChange((MYPCSC_SCARDCONTEXT) hContext, (MYPCSC_DWORD) dwTimeout,
+	/* Workaround for a bug in pcsclite, timeout value of 0 is handled as INFINIT
+	   but is by Windows PCSC spec. used for polling current state.
+	 */
+	if (dwTimeout == 0)
+	  dwTimeout = 1;
+	rv = SCardGetStatusChange(myHContext, (MYPCSC_DWORD) dwTimeout,
 				  myRsArray, (MYPCSC_DWORD) dwCount);
 	copyReaderState_MyPCSCToServer(myRsArray, rsArray, (MYPCSC_DWORD) dwCount);
 
@@ -1110,8 +1211,8 @@ TS_SCardGetStatusChange(STREAM in, STREAM out, RD_BOOL wide)
 	for (i = 0, cur = rsArray; i < dwCount; i++, cur++)
 	{
 		DEBUG_SCARD(("SCARD:    \"%s\"\n", cur->szReader ? cur->szReader : "NULL"));
-		DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n",
-			     (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
+		DEBUG_SCARD(("SCARD:        user: %p, state: 0x%08x, event: 0x%08x\n",
+			     cur->pvUserData, (unsigned) cur->dwCurrentState,
 			     (unsigned) cur->dwEventState));
 
 		/* Do endian swaps... */
@@ -1132,11 +1233,16 @@ TS_SCardCancel(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
 
 	in->p += 0x1C;
 	in_uint32_le(in, hContext);
-	DEBUG_SCARD(("SCARD: SCardCancel(context: 0x%08x)\n", (unsigned) hContext));
-	rv = SCardCancel((MYPCSC_SCARDCONTEXT) hContext);
+
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+
+	DEBUG_SCARD(("SCARD: SCardCancel(context: 0x%08x [0x%08lx])\n", (unsigned) hContext,
+		     (unsigned long) myHContext));
+	rv = SCardCancel(myHContext);
 	if (rv != SCARD_S_SUCCESS)
 	{
 		DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n",
@@ -1156,6 +1262,8 @@ TS_SCardLocateCardsByATR(STREAM in, STREAM out, RD_BOOL wide)
 	int i, j, k;
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
+
 	/* The SCARD_ATRMASK_L struct doesn't contain any longs or DWORDs -
 	   no need to split into SERVER_ and MYPCSC_ */
 	LPSCARD_ATRMASK_L pAtrMasks, cur;
@@ -1174,13 +1282,14 @@ TS_SCardLocateCardsByATR(STREAM in, STREAM out, RD_BOOL wide)
 	in_uint8a(in, pAtrMasks, atrMaskCount * sizeof(SCARD_ATRMASK_L));
 
 	in_uint32_le(in, readerCount);
-	rsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(SCARD_READERSTATE_A));
+	rsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(SCARD_READERSTATE));
 	if (!rsArray)
 		return SC_returnNoMemoryError(&lcHandle, in, out);
-	memset(rsArray, 0, readerCount * sizeof(SCARD_READERSTATE_A));
+	memset(rsArray, 0, readerCount * sizeof(SCARD_READERSTATE));
+
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
 
-	DEBUG_SCARD(("SCARD: SCardLocateCardsByATR(context: 0x%08x, atrs: %d, readers: %d)\n",
-		     (unsigned) hContext, (int) atrMaskCount, (int) readerCount));
+	DEBUG_SCARD(("SCARD: SCardLocateCardsByATR(context: 0x%08x [0x%08lx], atrs: %d, readers: %d)\n", (unsigned) hContext, (unsigned long) myHContext, (int) atrMaskCount, (int) readerCount));
 
 	for (i = 0, cur = pAtrMasks; i < atrMaskCount; i++, cur++)
 	{
@@ -1222,8 +1331,8 @@ TS_SCardLocateCardsByATR(STREAM in, STREAM out, RD_BOOL wide)
 
 		inReaderName(&lcHandle, in, (char **) &rsCur->szReader, wide);
 		DEBUG_SCARD(("SCARD:    \"%s\"\n", rsCur->szReader ? rsCur->szReader : "NULL"));
-		DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n",
-			     (unsigned) rsCur->pvUserData, (unsigned) rsCur->dwCurrentState,
+		DEBUG_SCARD(("SCARD:        user: %p, state: 0x%08x, event: 0x%08x\n",
+			     rsCur->pvUserData, (unsigned) rsCur->dwCurrentState,
 			     (unsigned) rsCur->dwEventState));
 	}
 	memcpy(ResArray, rsArray, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));
@@ -1233,8 +1342,7 @@ TS_SCardLocateCardsByATR(STREAM in, STREAM out, RD_BOOL wide)
 	if (!myRsArray)
 		return SC_returnNoMemoryError(&lcHandle, in, out);
 	copyReaderState_ServerToMyPCSC(rsArray, myRsArray, readerCount);
-	rv = SCardGetStatusChange((MYPCSC_SCARDCONTEXT) hContext, 0x00000001, myRsArray,
-				  readerCount);
+	rv = SCardGetStatusChange(myHContext, 0x00000001, myRsArray, readerCount);
 	copyReaderState_MyPCSCToServer(myRsArray, rsArray, readerCount);
 	if (rv != SCARD_S_SUCCESS)
 	{
@@ -1262,10 +1370,10 @@ TS_SCardLocateCardsByATR(STREAM in, STREAM out, RD_BOOL wide)
 				if (equal)
 				{
 					rsCur->dwEventState |= 0x00000040;	/* SCARD_STATE_ATRMATCH 0x00000040 */
-					memcpy(ResArray + j, rsCur, sizeof(SCARD_READERSTATE_A));
+					memcpy(ResArray + j, rsCur, sizeof(SCARD_READERSTATE));
 					DEBUG_SCARD(("SCARD:    \"%s\"\n",
 						     rsCur->szReader ? rsCur->szReader : "NULL"));
-					DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n", (unsigned) rsCur->pvUserData, (unsigned) rsCur->dwCurrentState, (unsigned) rsCur->dwEventState));
+					DEBUG_SCARD(("SCARD:        user: %p, state: 0x%08x, event: 0x%08x\n", rsCur->pvUserData, (unsigned) rsCur->dwCurrentState, (unsigned) rsCur->dwEventState));
 				}
 			}
 		}
@@ -1283,7 +1391,7 @@ TS_SCardLocateCardsByATR(STREAM in, STREAM out, RD_BOOL wide)
 		rsCur->cbAtr = swap32(rsCur->cbAtr);
 
 		out_uint8p(out, (void *) ((unsigned char **) rsCur + 2),
-			   sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
+			   sizeof(SCARD_READERSTATE) - 2 * sizeof(unsigned char *));
 	}
 
 	outForceAlignment(out, 8);
@@ -1300,9 +1408,9 @@ TS_SCardBeginTransaction(STREAM in, STREAM out)
 
 	in->p += 0x30;
 	in_uint32_le(in, hCard);
-	myHCard = scHandleToMyPCSC(hCard);
-	DEBUG_SCARD(("SCARD: SCardBeginTransaction(hcard: 0x%08x [0x%08lx])\n",
-		     (unsigned) hCard, (unsigned long) myHCard));
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
+	DEBUG_SCARD(("SCARD: SCardBeginTransaction(hcard: 0x%08x [0x%lx])\n",
+		     (unsigned) hCard, myHCard));
 	rv = SCardBeginTransaction(myHCard);
 	if (rv != SCARD_S_SUCCESS)
 	{
@@ -1329,13 +1437,10 @@ TS_SCardEndTransaction(STREAM in, STREAM out)
 	in_uint32_le(in, dwDisposition);
 	in->p += 0x0C;
 	in_uint32_le(in, hCard);
-	myHCard = scHandleToMyPCSC(hCard);
 
-	DEBUG_SCARD(("[hCard = 0x%.8x]\n", (unsigned int) hCard));
-	DEBUG_SCARD(("[myHCard = 0x%016lx]\n", (unsigned long) myHCard));
-	DEBUG_SCARD(("[dwDisposition = 0x%.8x]\n", (unsigned int) dwDisposition));
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
 
-	DEBUG_SCARD(("SCARD: SCardEndTransaction(hcard: 0x%08x [0x%08lx], disposition: 0x%08x)\n",
+	DEBUG_SCARD(("SCARD: SCardEndTransaction(hcard: 0x%08x [0x%lx], disposition: 0x%08x)\n",
 		     (unsigned) hCard, (unsigned long) myHCard, (unsigned) dwDisposition));
 	rv = SCardEndTransaction(myHCard, (MYPCSC_DWORD) dwDisposition);
 	if (rv != SCARD_S_SUCCESS)
@@ -1414,7 +1519,7 @@ TS_SCardTransmit(STREAM in, STREAM out)
 
 	in->p += 0x04;
 	in_uint32_le(in, hCard);
-	myHCard = scHandleToMyPCSC(hCard);
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
 
 	if (map[2] & INPUT_LINKED)
 	{
@@ -1583,8 +1688,7 @@ TS_SCardStatus(STREAM in, STREAM out, RD_BOOL wide)
 	in->p += 0x0C;
 	in_uint32_le(in, hCard);
 	in->p += 0x04;
-	myHCard = scHandleToMyPCSC(hCard);
-
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
 	DEBUG_SCARD(("SCARD: SCardStatus(hcard: 0x%08x [0x%08lx], reader len: %d bytes, atr len: %d bytes)\n", (unsigned) hCard, (unsigned long) myHCard, (int) dwReaderLen, (int) dwAtrLen));
 
 	if (dwReaderLen <= 0 || dwReaderLen == SCARD_AUTOALLOCATE || dwReaderLen > SCARD_MAX_MEM)
@@ -1707,7 +1811,7 @@ TS_SCardState(STREAM in, STREAM out)
 	in->p += 0x0C;
 	in_uint32_le(in, hCard);
 	in->p += 0x04;
-	myHCard = scHandleToMyPCSC(hCard);
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
 
 	DEBUG_SCARD(("SCARD: SCardState(hcard: 0x%08x [0x%08lx], atr len: %d bytes)\n",
 		     (unsigned) hCard, (unsigned long) myHCard, (int) dwAtrLen));
@@ -1798,6 +1902,7 @@ TS_SCardListReaderGroups(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
 	SERVER_DWORD dwGroups;
 	MYPCSC_DWORD groups;
 	char *szGroups;
@@ -1808,8 +1913,10 @@ TS_SCardListReaderGroups(STREAM in, STREAM out)
 	in->p += 0x04;
 	in_uint32_le(in, hContext);
 
-	DEBUG_SCARD(("SCARD: SCardListReaderGroups(context: 0x%08x, groups: %d)\n",
-		     (unsigned) hContext, (int) dwGroups));
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+
+	DEBUG_SCARD(("SCARD: SCardListReaderGroups(context: 0x%08x [0x%08lx], groups: %d)\n",
+		     (unsigned) hContext, (unsigned int) myHContext, (int) dwGroups));
 
 	if (dwGroups <= 0 || dwGroups == SCARD_AUTOALLOCATE || dwGroups > SCARD_MAX_MEM)
 		dwGroups = SCARD_MAX_MEM;
@@ -1819,7 +1926,7 @@ TS_SCardListReaderGroups(STREAM in, STREAM out)
 		return SC_returnNoMemoryError(&lcHandle, in, out);
 
 	groups = dwGroups;
-	rv = SCardListReaderGroups((MYPCSC_SCARDCONTEXT) hContext, szGroups, &groups);
+	rv = SCardListReaderGroups(myHContext, szGroups, &groups);
 	dwGroups = groups;
 
 	if (rv)
@@ -1871,9 +1978,7 @@ TS_SCardGetAttrib(STREAM in, STREAM out)
 	in_uint32_le(in, dwAttrLen);
 	in->p += 0x0C;
 	in_uint32_le(in, hCard);
-	myHCard = scHandleToMyPCSC(hCard);
-
-	dwAttrId = dwAttrId & 0x0000FFFF;
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
 
 	DEBUG_SCARD(("SCARD: SCardGetAttrib(hcard: 0x%08x [0x%08lx], attrib: 0x%08x (%d bytes))\n",
 		     (unsigned) hCard, (unsigned long) myHCard,
@@ -1887,7 +1992,7 @@ TS_SCardGetAttrib(STREAM in, STREAM out)
 		pbAttr = NULL;
 	else if ((dwAttrLen < 0) || (dwAttrLen > SCARD_MAX_MEM))
 	{
-		dwAttrLen = SCARD_AUTOALLOCATE;
+		dwAttrLen = (SERVER_DWORD) SCARD_AUTOALLOCATE;
 		pbAttr = NULL;
 	}
 	else
@@ -1901,26 +2006,6 @@ TS_SCardGetAttrib(STREAM in, STREAM out)
 	rv = SCardGetAttrib(myHCard, (MYPCSC_DWORD) dwAttrId, pbAttr, &attrLen);
 	dwAttrLen = attrLen;
 
-	if (dwAttrId == 0x00000100 && rv != SCARD_S_SUCCESS)
-	{
-		DEBUG_SCARD(("SCARD:    Faking attribute ATTR_VENDOR_NAME\n"));
-		pthread_mutex_lock(&hcardAccess);
-		PSCHCardRec hcard = hcardFirst;
-		while (hcard)
-		{
-			if (hcard->hCard == hCard)
-			{
-				dwAttrLen = strlen(hcard->vendor);
-				memcpy(pbAttr, hcard->vendor, dwAttrLen);
-				rv = SCARD_S_SUCCESS;
-				break;
-			}
-			hcard = hcard->next;
-		}
-		pthread_mutex_unlock(&hcardAccess);
-		DEBUG_SCARD(("[0x%.8x]\n", (unsigned int) rv));
-	}
-
 	if (rv != SCARD_S_SUCCESS)
 	{
 		DEBUG_SCARD(("SCARD: -> Failure: %s (0x%08x)\n",
@@ -1970,8 +2055,6 @@ TS_SCardSetAttrib(STREAM in, STREAM out)
 	in_uint32_le(in, hCard);
 	myHCard = scHandleToMyPCSC(hCard);
 
-	dwAttrId = dwAttrId & 0x0000FFFF;
-
 	DEBUG_SCARD(("SCARD: SCardSetAttrib(hcard: 0x%08x [0x%08lx], attrib: 0x%08x (%d bytes))\n",
 		     (unsigned) hCard, (unsigned long) myHCard,
 		     (unsigned) dwAttrId, (int) dwAttrLen));
@@ -2013,6 +2096,7 @@ TS_SCardControl(STREAM in, STREAM out)
 {
 	MYPCSC_DWORD rv;
 	SERVER_SCARDCONTEXT hContext;
+	MYPCSC_SCARDCONTEXT myHContext;
 	SERVER_SCARDHANDLE hCard;
 	MYPCSC_SCARDHANDLE myHCard;
 	SERVER_DWORD map[3];
@@ -2051,7 +2135,10 @@ TS_SCardControl(STREAM in, STREAM out)
 		}
 	}
 
-	DEBUG_SCARD(("SCARD: SCardControl(context: 0x%08x, hcard: 0x%08x, code: 0x%08x, in: %d bytes, out: %d bytes)\n", (unsigned) hContext, (unsigned) hCard, (unsigned) dwControlCode, (int) nInBufferSize, (int) nOutBufferSize));
+	myHCard = _scard_handle_list_get_pcsc_handle(hCard);
+	myHContext = _scard_handle_list_get_pcsc_handle(hContext);
+
+	DEBUG_SCARD(("SCARD: SCardControl(context: 0x%08x [0x%08lx], hcard: 0x%08x [0x%08lx], code: 0x%08x, in: %d bytes, out: %d bytes)\n", (unsigned) hContext, (unsigned long) myHContext, (unsigned) hCard, (unsigned long) myHCard, (unsigned) dwControlCode, (int) nInBufferSize, (int) nOutBufferSize));
 
 	/* Is this a proper Windows smart card ioctl? */
 	if ((dwControlCode & 0xffff0000) == (49 << 16))
@@ -2082,7 +2169,7 @@ TS_SCardControl(STREAM in, STREAM out)
 		return SC_returnNoMemoryError(&lcHandle, in, out);
 
 	sc_nBytesReturned = nBytesReturned;
-	myHCard = scHandleToMyPCSC(hCard);
+
 #ifdef WITH_PCSC120
 	rv = SCardControl(myHCard, pInBuffer, (MYPCSC_DWORD) nInBufferSize, pOutBuffer,
 			  &sc_nBytesReturned);
@@ -2379,6 +2466,7 @@ SC_addToQueue(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out)
 		data->memHandle = lcHandle;
 		data->device = curDevice;
 		data->id = curId;
+		data->epoch = curEpoch;
 		data->handle = handle;
 		data->request = request;
 		data->in = duplicateStream(&(data->memHandle), in, 0, SC_TRUE);
@@ -2450,7 +2538,14 @@ SC_deviceControl(PSCThreadData data)
 	size_t buffer_len = 0;
 	scard_device_control(data->handle, data->request, data->in, data->out);
 	buffer_len = (size_t) data->out->p - (size_t) data->out->data;
-	rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data, buffer_len);
+
+	/* if iorequest belongs to another epoch, don't send response
+	   back to server due to it's considered as abdonend.
+	 */
+	if (data->epoch == curEpoch)
+		rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data,
+				      buffer_len);
+
 	SC_destroyThreadData(data);
 }
 
diff --git a/src/VBox/RDP/client/scard.h b/src/VBox/RDP/client-1.8.3/scard.h
similarity index 97%
rename from src/VBox/RDP/client/scard.h
rename to src/VBox/RDP/client-1.8.3/scard.h
index f5eac92..1e2779f 100644
--- a/src/VBox/RDP/client/scard.h
+++ b/src/VBox/RDP/client-1.8.3/scard.h
@@ -59,8 +59,7 @@ typedef SCARDHANDLE MYPCSC_SCARDHANDLE;
 typedef uint32_t SERVER_SCARDCONTEXT;
 typedef uint32_t SERVER_SCARDHANDLE;
 
-typedef SCARD_READERSTATE_A MYPCSC_SCARD_READERSTATE_A;
-typedef LPSCARD_READERSTATE_A MYPCSC_LPSCARD_READERSTATE_A;
+typedef SCARD_READERSTATE MYPCSC_SCARD_READERSTATE_A, *MYPCSC_LPSCARD_READERSTATE_A;
 
 typedef struct
 {
@@ -69,7 +68,7 @@ typedef struct
 	SERVER_DWORD dwCurrentState;
 	SERVER_DWORD dwEventState;
 	SERVER_DWORD cbAtr;
-	unsigned char rgbAtr[MAX_ATR_SIZE];
+	unsigned char rgbAtr[36];
 }
 SERVER_SCARD_READERSTATE_A;
 
@@ -164,6 +163,7 @@ typedef struct _TSCThreadData
 {
 	uint32 device;
 	uint32 id;
+	uint32 epoch;
 	RD_NTHANDLE handle;
 	uint32 request;
 	STREAM in;
diff --git a/src/VBox/RDP/client/seamless.c b/src/VBox/RDP/client-1.8.3/seamless.c
similarity index 91%
rename from src/VBox/RDP/client/seamless.c
rename to src/VBox/RDP/client-1.8.3/seamless.c
index 0603830..96458d6 100644
--- a/src/VBox/RDP/client/seamless.c
+++ b/src/VBox/RDP/client-1.8.3/seamless.c
@@ -3,6 +3,7 @@
    Seamless Windows support
    Copyright 2005-2008 Peter Astrand <astrand at cendio.se> for Cendio AB
    Copyright 2007-2008 Pierre Ossman <ossman at cendio.se> for Cendio AB
+   Copyright 2013-2014 Henrik Andersson  <hean01 at cendio.se> for Cendio AB   
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -40,6 +41,7 @@
 extern RD_BOOL g_seamless_rdp;
 static VCHANNEL *seamless_channel;
 static unsigned int seamless_serial;
+static char *seamless_rest = NULL;
 static char icon_buf[1024];
 
 static char *
@@ -381,7 +383,6 @@ static void
 seamless_process(STREAM s)
 {
 	unsigned int pkglen;
-	static char *rest = NULL;
 	char *buf;
 
 	pkglen = s->end - s->p;
@@ -393,7 +394,7 @@ seamless_process(STREAM s)
 	hexdump(s->p, pkglen);
 #endif
 
-	str_handle_lines(buf, &rest, seamless_line_handler, NULL);
+	str_handle_lines(buf, &seamless_rest, seamless_line_handler, NULL);
 
 	xfree(buf);
 }
@@ -413,6 +414,15 @@ seamless_init(void)
 	return (seamless_channel != NULL);
 }
 
+void
+seamless_reset_state(void)
+{
+	if (seamless_rest != NULL)
+	{
+		xfree(seamless_rest);
+		seamless_rest = NULL;
+	}
+}
 
 static unsigned int
 seamless_send(const char *command, const char *format, ...)
@@ -420,7 +430,7 @@ seamless_send(const char *command, const char *format, ...)
 	STREAM s;
 	size_t len;
 	va_list argp;
-	char buf[1025];
+	char *escaped, buf[1025];
 
 	len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, seamless_serial);
 
@@ -432,6 +442,11 @@ seamless_send(const char *command, const char *format, ...)
 
 	assert(len < (sizeof(buf) - 1));
 
+	escaped = utils_string_escape(buf);
+	len = snprintf(buf, sizeof(buf), "%s", escaped);
+	free(escaped);
+	assert(len < (sizeof(buf) - 1));
+
 	buf[len] = '\n';
 	buf[len + 1] = '\0';
 
@@ -440,7 +455,7 @@ seamless_send(const char *command, const char *format, ...)
 	s = channel_init(seamless_channel, len);
 	out_uint8p(s, buf, len) s_mark_end(s);
 
-	DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
+	DEBUG_SEAMLESS(("seamlessrdp sending:%s", buf));
 
 #if 0
 	printf("seamless send:\n");
@@ -524,3 +539,27 @@ seamless_send_destroy(unsigned long id)
 {
 	return seamless_send("DESTROY", "0x%08lx", id);
 }
+
+unsigned int
+seamless_send_spawn(char *cmdline)
+{
+	unsigned int res;
+	if (!g_seamless_rdp)
+		return (unsigned int) -1;
+
+	res = seamless_send("SPAWN", cmdline);
+
+	return res;
+}
+
+unsigned int
+seamless_send_persistent(RD_BOOL enable)
+{
+	unsigned int res;
+	if (!g_seamless_rdp)
+		return (unsigned int) -1;
+	printf("%s persistent seamless mode.\n", enable?"Enable":"Disable");
+	res = seamless_send("PERSISTENT", "%d", enable);
+	
+	return res;
+}
diff --git a/src/VBox/RDP/client/seamless.h b/src/VBox/RDP/client-1.8.3/seamless.h
similarity index 91%
rename from src/VBox/RDP/client/seamless.h
rename to src/VBox/RDP/client-1.8.3/seamless.h
index 425f606..836062e 100644
--- a/src/VBox/RDP/client/seamless.h
+++ b/src/VBox/RDP/client-1.8.3/seamless.h
@@ -1,7 +1,7 @@
 /*
    rdesktop: A Remote Desktop Protocol client.
    Seamless Windows support
-   Copyright (C) Peter Astrand <astrand at cendio.se> 2005-2008
+   Copyright 2005-2008 Peter Astrand <astrand at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/src/VBox/RDP/client/secure.c b/src/VBox/RDP/client-1.8.3/secure.c
similarity index 73%
rename from src/VBox/RDP/client/secure.c
rename to src/VBox/RDP/client-1.8.3/secure.c
index c298243..e7c05fa 100644
--- a/src/VBox/RDP/client/secure.c
+++ b/src/VBox/RDP/client-1.8.3/secure.c
@@ -39,16 +39,18 @@ extern int g_keyboard_subtype;
 extern int g_keyboard_functionkeys;
 extern RD_BOOL g_encryption;
 extern RD_BOOL g_licence_issued;
-extern RD_BOOL g_use_rdp5;
+extern RD_BOOL g_licence_error_result;
+extern RDP_VERSION g_rdp_version;
 extern RD_BOOL g_console_session;
+extern uint32 g_redirect_session_id;
 extern int g_server_depth;
 extern VCHANNEL g_channels[];
 extern unsigned int g_num_channels;
 extern uint8 g_client_random[SEC_RANDOM_SIZE];
 
 static int g_rc4_key_len;
-static SSL_RC4 g_rc4_decrypt_key;
-static SSL_RC4 g_rc4_encrypt_key;
+static RDSSL_RC4 g_rc4_decrypt_key;
+static RDSSL_RC4 g_rc4_encrypt_key;
 static uint32 g_server_public_key_len;
 
 static uint8 g_sec_sign_key[16];
@@ -83,25 +85,25 @@ sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
 {
 	uint8 shasig[20];
 	uint8 pad[4];
-	SSL_SHA1 sha1;
-	SSL_MD5 md5;
+	RDSSL_SHA1 sha1;
+	RDSSL_MD5 md5;
 	int i;
 
 	for (i = 0; i < 3; i++)
 	{
 		memset(pad, salt + i, i + 1);
 
-		ssl_sha1_init(&sha1);
-		ssl_sha1_update(&sha1, pad, i + 1);
-		ssl_sha1_update(&sha1, in, 48);
-		ssl_sha1_update(&sha1, salt1, 32);
-		ssl_sha1_update(&sha1, salt2, 32);
-		ssl_sha1_final(&sha1, shasig);
-
-		ssl_md5_init(&md5);
-		ssl_md5_update(&md5, in, 48);
-		ssl_md5_update(&md5, shasig, 20);
-		ssl_md5_final(&md5, &out[i * 16]);
+		rdssl_sha1_init(&sha1);
+		rdssl_sha1_update(&sha1, pad, i + 1);
+		rdssl_sha1_update(&sha1, in, 48);
+		rdssl_sha1_update(&sha1, salt1, 32);
+		rdssl_sha1_update(&sha1, salt2, 32);
+		rdssl_sha1_final(&sha1, shasig);
+
+		rdssl_md5_init(&md5);
+		rdssl_md5_update(&md5, in, 48);
+		rdssl_md5_update(&md5, shasig, 20);
+		rdssl_md5_final(&md5, &out[i * 16]);
 	}
 }
 
@@ -111,13 +113,38 @@ sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
 void
 sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
 {
-	SSL_MD5 md5;
+	RDSSL_MD5 md5;
 
-	ssl_md5_init(&md5);
-	ssl_md5_update(&md5, in, 16);
-	ssl_md5_update(&md5, salt1, 32);
-	ssl_md5_update(&md5, salt2, 32);
-	ssl_md5_final(&md5, out);
+	rdssl_md5_init(&md5);
+	rdssl_md5_update(&md5, in, 16);
+	rdssl_md5_update(&md5, salt1, 32);
+	rdssl_md5_update(&md5, salt2, 32);
+	rdssl_md5_final(&md5, out);
+}
+
+/*
+ * 16-byte sha1 hash
+ */
+void
+sec_hash_sha1_16(uint8 * out, uint8 * in, uint8 * salt1)
+{
+	RDSSL_SHA1 sha1;
+	rdssl_sha1_init(&sha1);
+	rdssl_sha1_update(&sha1, in, 16);
+	rdssl_sha1_update(&sha1, salt1, 16);
+	rdssl_sha1_final(&sha1, out);
+}
+
+/* create string from hash */
+void
+sec_hash_to_string(char *out, int out_size, uint8 * in, int in_size)
+{
+	int k;
+	memset(out, 0, out_size);
+	for (k = 0; k < in_size; k++, out += 2)
+	{
+		sprintf(out, "%.2x", in[k]);
+	}
 }
 
 /* Reduce key entropy from 64 to 40 bits */
@@ -171,8 +198,8 @@ sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size
 	memcpy(g_sec_encrypt_update_key, g_sec_encrypt_key, 16);
 
 	/* Initialise RC4 state arrays */
-	ssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
-	ssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
+	rdssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
+	rdssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
 }
 
 static uint8 pad_54[40] = {
@@ -206,23 +233,23 @@ sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 *
 	uint8 shasig[20];
 	uint8 md5sig[16];
 	uint8 lenhdr[4];
-	SSL_SHA1 sha1;
-	SSL_MD5 md5;
+	RDSSL_SHA1 sha1;
+	RDSSL_MD5 md5;
 
 	buf_out_uint32(lenhdr, datalen);
 
-	ssl_sha1_init(&sha1);
-	ssl_sha1_update(&sha1, session_key, keylen);
-	ssl_sha1_update(&sha1, pad_54, 40);
-	ssl_sha1_update(&sha1, lenhdr, 4);
-	ssl_sha1_update(&sha1, data, datalen);
-	ssl_sha1_final(&sha1, shasig);
+	rdssl_sha1_init(&sha1);
+	rdssl_sha1_update(&sha1, session_key, keylen);
+	rdssl_sha1_update(&sha1, pad_54, 40);
+	rdssl_sha1_update(&sha1, lenhdr, 4);
+	rdssl_sha1_update(&sha1, data, datalen);
+	rdssl_sha1_final(&sha1, shasig);
 
-	ssl_md5_init(&md5);
-	ssl_md5_update(&md5, session_key, keylen);
-	ssl_md5_update(&md5, pad_92, 48);
-	ssl_md5_update(&md5, shasig, 20);
-	ssl_md5_final(&md5, md5sig);
+	rdssl_md5_init(&md5);
+	rdssl_md5_update(&md5, session_key, keylen);
+	rdssl_md5_update(&md5, pad_92, 48);
+	rdssl_md5_update(&md5, shasig, 20);
+	rdssl_md5_final(&md5, md5sig);
 
 	memcpy(signature, md5sig, siglen);
 }
@@ -232,24 +259,24 @@ static void
 sec_update(uint8 * key, uint8 * update_key)
 {
 	uint8 shasig[20];
-	SSL_SHA1 sha1;
-	SSL_MD5 md5;
-	SSL_RC4 update;
+	RDSSL_SHA1 sha1;
+	RDSSL_MD5 md5;
+	RDSSL_RC4 update;
 
-	ssl_sha1_init(&sha1);
-	ssl_sha1_update(&sha1, update_key, g_rc4_key_len);
-	ssl_sha1_update(&sha1, pad_54, 40);
-	ssl_sha1_update(&sha1, key, g_rc4_key_len);
-	ssl_sha1_final(&sha1, shasig);
+	rdssl_sha1_init(&sha1);
+	rdssl_sha1_update(&sha1, update_key, g_rc4_key_len);
+	rdssl_sha1_update(&sha1, pad_54, 40);
+	rdssl_sha1_update(&sha1, key, g_rc4_key_len);
+	rdssl_sha1_final(&sha1, shasig);
 
-	ssl_md5_init(&md5);
-	ssl_md5_update(&md5, update_key, g_rc4_key_len);
-	ssl_md5_update(&md5, pad_92, 48);
-	ssl_md5_update(&md5, shasig, 20);
-	ssl_md5_final(&md5, key);
+	rdssl_md5_init(&md5);
+	rdssl_md5_update(&md5, update_key, g_rc4_key_len);
+	rdssl_md5_update(&md5, pad_92, 48);
+	rdssl_md5_update(&md5, shasig, 20);
+	rdssl_md5_final(&md5, key);
 
-	ssl_rc4_set_key(&update, key, g_rc4_key_len);
-	ssl_rc4_crypt(&update, key, key, g_rc4_key_len);
+	rdssl_rc4_set_key(&update, key, g_rc4_key_len);
+	rdssl_rc4_crypt(&update, key, key, g_rc4_key_len);
 
 	if (g_rc4_key_len == 8)
 		sec_make_40bit(key);
@@ -262,11 +289,11 @@ sec_encrypt(uint8 * data, int length)
 	if (g_sec_encrypt_use_count == 4096)
 	{
 		sec_update(g_sec_encrypt_key, g_sec_encrypt_update_key);
-		ssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
+		rdssl_rc4_set_key(&g_rc4_encrypt_key, g_sec_encrypt_key, g_rc4_key_len);
 		g_sec_encrypt_use_count = 0;
 	}
 
-	ssl_rc4_crypt(&g_rc4_encrypt_key, data, data, length);
+	rdssl_rc4_crypt(&g_rc4_encrypt_key, data, data, length);
 	g_sec_encrypt_use_count++;
 }
 
@@ -277,11 +304,11 @@ sec_decrypt(uint8 * data, int length)
 	if (g_sec_decrypt_use_count == 4096)
 	{
 		sec_update(g_sec_decrypt_key, g_sec_decrypt_update_key);
-		ssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
+		rdssl_rc4_set_key(&g_rc4_decrypt_key, g_sec_decrypt_key, g_rc4_key_len);
 		g_sec_decrypt_use_count = 0;
 	}
 
-	ssl_rc4_crypt(&g_rc4_decrypt_key, data, data, length);
+	rdssl_rc4_crypt(&g_rc4_decrypt_key, data, data, length);
 	g_sec_decrypt_use_count++;
 }
 
@@ -290,7 +317,7 @@ static void
 sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
 		uint8 * exponent)
 {
-	ssl_rsa_encrypt(out, in, len, modulus_size, modulus, exponent);
+	rdssl_rsa_encrypt(out, in, len, modulus_size, modulus, exponent);
 }
 
 /* Initialise secure transport packet */
@@ -300,7 +327,7 @@ sec_init(uint32 flags, int maxlen)
 	int hdrlen;
 	STREAM s;
 
-	if (!g_licence_issued)
+	if (!g_licence_issued && !g_licence_error_result)
 		hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
 	else
 		hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
@@ -321,7 +348,7 @@ sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
 #endif
 
 	s_pop_layer(s, sec_hdr);
-	if (!g_licence_issued || (flags & SEC_ENCRYPT))
+	if ((!g_licence_issued && !g_licence_error_result) || (flags & SEC_ENCRYPT))
 		out_uint32_le(s, flags);
 
 	if (flags & SEC_ENCRYPT)
@@ -374,10 +401,10 @@ sec_establish_key(void)
 
 /* Output connect initial data blob */
 static void
-sec_out_mcs_data(STREAM s)
+sec_out_mcs_data(STREAM s, uint32 selected_protocol)
 {
 	int hostlen = 2 * strlen(g_hostname);
-	int length = 158 + 76 + 12 + 4;
+	int length = 162 + 76 + 12 + 4;
 	unsigned int i;
 
 	if (g_num_channels > 0)
@@ -405,8 +432,8 @@ sec_out_mcs_data(STREAM s)
 
 	/* Client information */
 	out_uint16_le(s, SEC_TAG_CLI_INFO);
-	out_uint16_le(s, 212);	/* length */
-	out_uint16_le(s, g_use_rdp5 ? 4 : 1);	/* RDP version. 1 == RDP4, 4 == RDP5. */
+	out_uint16_le(s, 216);	/* length */
+	out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 4 : 1);	/* RDP version. 1 == RDP4, 4 >= RDP5 to RDP8 */
 	out_uint16_le(s, 8);
 	out_uint16_le(s, g_width);
 	out_uint16_le(s, g_height);
@@ -433,12 +460,22 @@ sec_out_mcs_data(STREAM s)
 	out_uint16_le(s, 0x0700);
 	out_uint8(s, 0);
 	out_uint32_le(s, 1);
-	out_uint8s(s, 64);	/* End of client info */
+	out_uint8s(s, 64);
+	out_uint32_le(s, selected_protocol);	/* End of client info */
 
-	out_uint16_le(s, SEC_TAG_CLI_4);
-	out_uint16_le(s, 12);
-	out_uint32_le(s, g_console_session ? 0xb : 9);
-	out_uint32(s, 0);
+	/* Write a Client Cluster Data (TS_UD_CS_CLUSTER) */
+	uint32 cluster_flags = 0;
+	out_uint16_le(s, SEC_TAG_CLI_CLUSTER);	/* header.type */
+	out_uint16_le(s, 12);	/* length */
+
+	cluster_flags |= SEC_CC_REDIRECTION_SUPPORTED;
+	cluster_flags |= (SEC_CC_REDIRECT_VERSION_3 << 2);
+
+	if (g_console_session || g_redirect_session_id != 0)
+		cluster_flags |= SEC_CC_REDIRECT_SESSIONID_FIELD_VALID;
+
+	out_uint32_le(s, cluster_flags);
+	out_uint32(s, g_redirect_session_id);
 
 	/* Client encryption settings */
 	out_uint16_le(s, SEC_TAG_CLI_CRYPT);
@@ -507,8 +544,8 @@ sec_parse_public_sig(STREAM s, uint32 len, uint8 * modulus, uint8 * exponent)
 	memset(signature, 0, sizeof(signature));
 	sig_len = len - 8;
 	in_uint8a(s, signature, sig_len);
-	return ssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, g_server_public_key_len,
-			  signature, sig_len);
+	return rdssl_sig_ok(exponent, SEC_EXPONENT_SIZE, modulus, g_server_public_key_len,
+			    signature, sig_len);
 }
 
 /* Parse a crypto information structure */
@@ -518,15 +555,19 @@ sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
 {
 	uint32 crypt_level, random_len, rsa_info_len;
 	uint32 cacert_len, cert_len, flags;
-	SSL_CERT *cacert, *server_cert;
-	SSL_RKEY *server_public_key;
+	RDSSL_CERT *cacert, *server_cert;
+	RDSSL_RKEY *server_public_key;
 	uint16 tag, length;
 	uint8 *next_tag, *end;
 
 	in_uint32_le(s, *rc4_key_size);	/* 1 = 40-bit, 2 = 128-bit */
 	in_uint32_le(s, crypt_level);	/* 1 = low, 2 = medium, 3 = high */
-	if (crypt_level == 0)	/* no encryption */
+	if (crypt_level == 0)
+	{
+		/* no encryption */
 		return False;
+	}
+
 	in_uint32_le(s, random_len);
 	in_uint32_le(s, rsa_info_len);
 
@@ -591,12 +632,12 @@ sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
 		for (; certcount > 2; certcount--)
 		{		/* ignore all the certificates between the root and the signing CA */
 			uint32 ignorelen;
-			SSL_CERT *ignorecert;
+			RDSSL_CERT *ignorecert;
 
 			DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
 			in_uint32_le(s, ignorelen);
 			DEBUG_RDP5(("Ignored Certificate length is %d\n", ignorelen));
-			ignorecert = ssl_cert_read(s->p, ignorelen);
+			ignorecert = rdssl_cert_read(s->p, ignorelen);
 			in_uint8s(s, ignorelen);
 			if (ignorecert == NULL)
 			{	/* XXX: error out? */
@@ -605,7 +646,7 @@ sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
 
 #ifdef WITH_DEBUG_RDP5
 			DEBUG_RDP5(("cert #%d (ignored):\n", certcount));
-			ssl_cert_print_fp(stdout, ignorecert);
+			rdssl_cert_print_fp(stdout, ignorecert);
 #endif
 		}
 		/* Do da funky X.509 stuffy
@@ -618,7 +659,7 @@ sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
 		 */
 		in_uint32_le(s, cacert_len);
 		DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
-		cacert = ssl_cert_read(s->p, cacert_len);
+		cacert = rdssl_cert_read(s->p, cacert_len);
 		in_uint8s(s, cacert_len);
 		if (NULL == cacert)
 		{
@@ -627,47 +668,47 @@ sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
 		}
 		in_uint32_le(s, cert_len);
 		DEBUG_RDP5(("Certificate length is %d\n", cert_len));
-		server_cert = ssl_cert_read(s->p, cert_len);
+		server_cert = rdssl_cert_read(s->p, cert_len);
 		in_uint8s(s, cert_len);
 		if (NULL == server_cert)
 		{
-			ssl_cert_free(cacert);
+			rdssl_cert_free(cacert);
 			error("Couldn't load Certificate from server\n");
 			return False;
 		}
-		if (!ssl_certs_ok(server_cert, cacert))
+		if (!rdssl_certs_ok(server_cert, cacert))
 		{
-			ssl_cert_free(server_cert);
-			ssl_cert_free(cacert);
+			rdssl_cert_free(server_cert);
+			rdssl_cert_free(cacert);
 			error("Security error CA Certificate invalid\n");
 			return False;
 		}
-		ssl_cert_free(cacert);
+		rdssl_cert_free(cacert);
 		in_uint8s(s, 16);	/* Padding */
-		server_public_key = ssl_cert_to_rkey(server_cert, &g_server_public_key_len);
+		server_public_key = rdssl_cert_to_rkey(server_cert, &g_server_public_key_len);
 		if (NULL == server_public_key)
 		{
 			DEBUG_RDP5(("Didn't parse X509 correctly\n"));
-			ssl_cert_free(server_cert);
+			rdssl_cert_free(server_cert);
 			return False;
 		}
-		ssl_cert_free(server_cert);
+		rdssl_cert_free(server_cert);
 		if ((g_server_public_key_len < SEC_MODULUS_SIZE) ||
 		    (g_server_public_key_len > SEC_MAX_MODULUS_SIZE))
 		{
 			error("Bad server public key size (%u bits)\n",
 			      g_server_public_key_len * 8);
-			ssl_rkey_free(server_public_key);
+			rdssl_rkey_free(server_public_key);
 			return False;
 		}
-		if (ssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
-					 modulus, SEC_MAX_MODULUS_SIZE) != 0)
+		if (rdssl_rkey_get_exp_mod(server_public_key, exponent, SEC_EXPONENT_SIZE,
+					   modulus, SEC_MAX_MODULUS_SIZE) != 0)
 		{
 			error("Problem extracting RSA exponent, modulus");
-			ssl_rkey_free(server_public_key);
+			rdssl_rkey_free(server_public_key);
 			return False;
 		}
-		ssl_rkey_free(server_public_key);
+		rdssl_rkey_free(server_public_key);
 		return True;	/* There's some garbage here we don't care about */
 	}
 	return s_check_end(s);
@@ -705,7 +746,7 @@ sec_process_srv_info(STREAM s)
 	DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
 	if (1 == g_server_rdp_version)
 	{
-		g_use_rdp5 = 0;
+		g_rdp_version = RDP_V4;
 		g_server_depth = 8;
 	}
 }
@@ -780,56 +821,67 @@ sec_recv(uint8 * rdpver)
 				return s;
 			}
 		}
-		if (g_encryption || !g_licence_issued)
+		if (g_encryption || (!g_licence_issued && !g_licence_error_result))
 		{
 			in_uint32_le(s, sec_flags);
 
-			if (sec_flags & SEC_ENCRYPT)
+			if (g_encryption)
 			{
-				in_uint8s(s, 8);	/* signature */
-				sec_decrypt(s->p, s->end - s->p);
-			}
+				if (sec_flags & SEC_ENCRYPT)
+				{
+					in_uint8s(s, 8);	/* signature */
+					sec_decrypt(s->p, s->end - s->p);
+				}
 
-			if (sec_flags & SEC_LICENCE_NEG)
-			{
-				licence_process(s);
-				continue;
-			}
+				if (sec_flags & SEC_LICENCE_NEG)
+				{
+					licence_process(s);
+					continue;
+				}
 
-			if (sec_flags & 0x0400)	/* SEC_REDIRECT_ENCRYPT */
-			{
-				uint8 swapbyte;
+				if (sec_flags & 0x0400)	/* SEC_REDIRECT_ENCRYPT */
+				{
+					uint8 swapbyte;
 
-				in_uint8s(s, 8);	/* signature */
-				sec_decrypt(s->p, s->end - s->p);
+					in_uint8s(s, 8);	/* signature */
+					sec_decrypt(s->p, s->end - s->p);
 
-				/* Check for a redirect packet, starts with 00 04 */
-				if (s->p[0] == 0 && s->p[1] == 4)
-				{
-					/* for some reason the PDU and the length seem to be swapped.
-					   This isn't good, but we're going to do a byte for byte
-					   swap.  So the first foure value appear as: 00 04 XX YY,
-					   where XX YY is the little endian length. We're going to
-					   use 04 00 as the PDU type, so after our swap this will look
-					   like: XX YY 04 00 */
-					swapbyte = s->p[0];
-					s->p[0] = s->p[2];
-					s->p[2] = swapbyte;
-
-					swapbyte = s->p[1];
-					s->p[1] = s->p[3];
-					s->p[3] = swapbyte;
-
-					swapbyte = s->p[2];
-					s->p[2] = s->p[3];
-					s->p[3] = swapbyte;
-				}
+					/* Check for a redirect packet, starts with 00 04 */
+					if (s->p[0] == 0 && s->p[1] == 4)
+					{
+						/* for some reason the PDU and the length seem to be swapped.
+						   This isn't good, but we're going to do a byte for byte
+						   swap.  So the first foure value appear as: 00 04 XX YY,
+						   where XX YY is the little endian length. We're going to
+						   use 04 00 as the PDU type, so after our swap this will look
+						   like: XX YY 04 00 */
+						swapbyte = s->p[0];
+						s->p[0] = s->p[2];
+						s->p[2] = swapbyte;
+
+						swapbyte = s->p[1];
+						s->p[1] = s->p[3];
+						s->p[3] = swapbyte;
+
+						swapbyte = s->p[2];
+						s->p[2] = s->p[3];
+						s->p[3] = swapbyte;
+					}
 #ifdef WITH_DEBUG
-				/* warning!  this debug statement will show passwords in the clear! */
-				hexdump(s->p, s->end - s->p);
+					/* warning!  this debug statement will show passwords in the clear! */
+					hexdump(s->p, s->end - s->p);
 #endif
+				}
+			}
+			else
+			{
+				if ((sec_flags & 0xffff) == SEC_LICENCE_NEG)
+				{
+					licence_process(s);
+					continue;
+				}
+				s->p -= 4;
 			}
-
 		}
 
 		if (channel != MCS_GLOBAL_CHANNEL)
@@ -848,19 +900,25 @@ sec_recv(uint8 * rdpver)
 
 /* Establish a secure connection */
 RD_BOOL
-sec_connect(char *server, char *username, RD_BOOL reconnect)
+sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
 {
+	uint32 selected_proto;
 	struct stream mcs_data;
 
+	/* Start a MCS connect sequence */
+	if (!mcs_connect_start(server, username, domain, password, reconnect, &selected_proto))
+		return False;
+
 	/* We exchange some RDP data during the MCS-Connect */
 	mcs_data.size = 512;
 	mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
-	sec_out_mcs_data(&mcs_data);
+	sec_out_mcs_data(&mcs_data, selected_proto);
 
-	if (!mcs_connect(server, &mcs_data, username, reconnect))
+	/* finialize the MCS connect sequence */
+	if (!mcs_connect_finalize(&mcs_data))
 		return False;
 
-	/*      sec_process_mcs_data(&mcs_data); */
+	/* sec_process_mcs_data(&mcs_data); */
 	if (g_encryption)
 		sec_establish_key();
 	xfree(mcs_data.data);
@@ -881,5 +939,7 @@ sec_reset_state(void)
 	g_server_rdp_version = 0;
 	g_sec_encrypt_use_count = 0;
 	g_sec_decrypt_use_count = 0;
+	g_licence_issued = 0;
+	g_licence_error_result = 0;
 	mcs_reset_state();
 }
diff --git a/src/VBox/RDP/client/serial.c b/src/VBox/RDP/client-1.8.3/serial.c
similarity index 98%
rename from src/VBox/RDP/client/serial.c
rename to src/VBox/RDP/client-1.8.3/serial.c
index d8cbb82..cc4bd14 100644
--- a/src/VBox/RDP/client/serial.c
+++ b/src/VBox/RDP/client-1.8.3/serial.c
@@ -709,7 +709,7 @@ serial_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uin
 static RD_NTSTATUS
 serial_device_control(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out)
 {
-	int flush_mask, purge_mask;
+	int purge_mask;
 	uint32 result, modemstate;
 	uint8 immediate;
 	SERIAL_DEVICE *pser_inf;
@@ -904,13 +904,13 @@ serial_device_control(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out)
 		case SERIAL_PURGE:
 			in_uint32(in, purge_mask);
 			DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask));
-			flush_mask = 0;
-			if (purge_mask & SERIAL_PURGE_TXCLEAR)
-				flush_mask |= TCOFLUSH;
-			if (purge_mask & SERIAL_PURGE_RXCLEAR)
-				flush_mask |= TCIFLUSH;
-			if (flush_mask != 0)
-				tcflush(handle, flush_mask);
+			if ((purge_mask & SERIAL_PURGE_TXCLEAR)
+			    && (purge_mask & SERIAL_PURGE_RXCLEAR))
+				tcflush(handle, TCIOFLUSH);
+			else if (purge_mask & SERIAL_PURGE_TXCLEAR)
+				tcflush(handle, TCOFLUSH);
+			else if (purge_mask & SERIAL_PURGE_RXCLEAR)
+				tcflush(handle, TCIFLUSH);
 			if (purge_mask & SERIAL_PURGE_TXABORT)
 				rdpdr_abort_io(handle, 4, RD_STATUS_CANCELLED);
 			if (purge_mask & SERIAL_PURGE_RXABORT)
diff --git a/src/VBox/RDP/client/ssl.c b/src/VBox/RDP/client-1.8.3/ssl.c
similarity index 77%
rename from src/VBox/RDP/client/ssl.c
rename to src/VBox/RDP/client-1.8.3/ssl.c
index 18ab673..dac5511 100644
--- a/src/VBox/RDP/client/ssl.c
+++ b/src/VBox/RDP/client-1.8.3/ssl.c
@@ -31,49 +31,49 @@
 #include "ssl.h"
 
 void
-ssl_sha1_init(SSL_SHA1 * sha1)
+rdssl_sha1_init(RDSSL_SHA1 * sha1)
 {
 	SHA1_Init(sha1);
 }
 
 void
-ssl_sha1_update(SSL_SHA1 * sha1, uint8 * data, uint32 len)
+rdssl_sha1_update(RDSSL_SHA1 * sha1, uint8 * data, uint32 len)
 {
 	SHA1_Update(sha1, data, len);
 }
 
 void
-ssl_sha1_final(SSL_SHA1 * sha1, uint8 * out_data)
+rdssl_sha1_final(RDSSL_SHA1 * sha1, uint8 * out_data)
 {
 	SHA1_Final(out_data, sha1);
 }
 
 void
-ssl_md5_init(SSL_MD5 * md5)
+rdssl_md5_init(RDSSL_MD5 * md5)
 {
 	MD5_Init(md5);
 }
 
 void
-ssl_md5_update(SSL_MD5 * md5, uint8 * data, uint32 len)
+rdssl_md5_update(RDSSL_MD5 * md5, uint8 * data, uint32 len)
 {
 	MD5_Update(md5, data, len);
 }
 
 void
-ssl_md5_final(SSL_MD5 * md5, uint8 * out_data)
+rdssl_md5_final(RDSSL_MD5 * md5, uint8 * out_data)
 {
 	MD5_Final(out_data, md5);
 }
 
 void
-ssl_rc4_set_key(SSL_RC4 * rc4, uint8 * key, uint32 len)
+rdssl_rc4_set_key(RDSSL_RC4 * rc4, uint8 * key, uint32 len)
 {
 	RC4_set_key(rc4, len, key);
 }
 
 void
-ssl_rc4_crypt(SSL_RC4 * rc4, uint8 * in_data, uint8 * out_data, uint32 len)
+rdssl_rc4_crypt(RDSSL_RC4 * rc4, uint8 * in_data, uint8 * out_data, uint32 len)
 {
 	RC4(rc4, len, in_data, out_data);
 }
@@ -93,8 +93,8 @@ reverse(uint8 * p, int len)
 }
 
 void
-ssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
-		uint8 * exponent)
+rdssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
+		  uint8 * exponent)
 {
 	BN_CTX *ctx;
 	BIGNUM mod, exp, x, y;
@@ -128,26 +128,26 @@ ssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * m
 	BN_CTX_free(ctx);
 }
 
-/* returns newly allocated SSL_CERT or NULL */
-SSL_CERT *
-ssl_cert_read(uint8 * data, uint32 len)
+/* returns newly allocated RDSSL_CERT or NULL */
+RDSSL_CERT *
+rdssl_cert_read(uint8 * data, uint32 len)
 {
 	/* this will move the data pointer but we don't care, we don't use it again */
 	return d2i_X509(NULL, (D2I_X509_CONST unsigned char **) &data, len);
 }
 
 void
-ssl_cert_free(SSL_CERT * cert)
+rdssl_cert_free(RDSSL_CERT * cert)
 {
 	X509_free(cert);
 }
 
-/* returns newly allocated SSL_RKEY or NULL */
-SSL_RKEY *
-ssl_cert_to_rkey(SSL_CERT * cert, uint32 * key_len)
+/* returns newly allocated RDSSL_RKEY or NULL */
+RDSSL_RKEY *
+rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len)
 {
 	EVP_PKEY *epk = NULL;
-	SSL_RKEY *lkey;
+	RDSSL_RKEY *lkey;
 	int nid;
 
 	/* By some reason, Microsoft sets the OID of the Public RSA key to
@@ -177,7 +177,7 @@ ssl_cert_to_rkey(SSL_CERT * cert, uint32 * key_len)
 
 /* returns boolean */
 RD_BOOL
-ssl_certs_ok(SSL_CERT * server_cert, SSL_CERT * cacert)
+rdssl_certs_ok(RDSSL_CERT * server_cert, RDSSL_CERT * cacert)
 {
 	/* Currently, we don't use the CA Certificate.
 	   FIXME:
@@ -192,21 +192,21 @@ ssl_certs_ok(SSL_CERT * server_cert, SSL_CERT * cacert)
 }
 
 int
-ssl_cert_print_fp(FILE * fp, SSL_CERT * cert)
+rdssl_cert_print_fp(FILE * fp, RDSSL_CERT * cert)
 {
 	return X509_print_fp(fp, cert);
 }
 
 void
-ssl_rkey_free(SSL_RKEY * rkey)
+rdssl_rkey_free(RDSSL_RKEY * rkey)
 {
 	RSA_free(rkey);
 }
 
 /* returns error */
 int
-ssl_rkey_get_exp_mod(SSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
-		     uint32 max_mod_len)
+rdssl_rkey_get_exp_mod(RDSSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
+		       uint32 max_mod_len)
 {
 	int len;
 
@@ -224,8 +224,8 @@ ssl_rkey_get_exp_mod(SSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint
 
 /* returns boolean */
 RD_BOOL
-ssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
-	   uint8 * signature, uint32 sig_len)
+rdssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
+	     uint8 * signature, uint32 sig_len)
 {
 	/* Currently, we don't check the signature
 	   FIXME:
@@ -235,7 +235,8 @@ ssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
 
 
 void
-ssl_hmac_md5(const void *key, int key_len, const unsigned char *msg, int msg_len, unsigned char *md)
+rdssl_hmac_md5(const void *key, int key_len, const unsigned char *msg, int msg_len,
+	       unsigned char *md)
 {
 	HMAC_CTX ctx;
 	HMAC_CTX_init(&ctx);
diff --git a/src/VBox/RDP/client/ssl.h b/src/VBox/RDP/client-1.8.3/ssl.h
similarity index 52%
rename from src/VBox/RDP/client/ssl.h
rename to src/VBox/RDP/client-1.8.3/ssl.h
index 23f49ee..1a03442 100644
--- a/src/VBox/RDP/client/ssl.h
+++ b/src/VBox/RDP/client-1.8.3/ssl.h
@@ -27,8 +27,8 @@
  * of the GPL is applied is otherwise unspecified.
  */
 
-#ifndef _SSL_H
-#define _SSL_H
+#ifndef _RDSSL_H
+#define _RDSSL_H
 
 #include <openssl/rc4.h>
 #include <openssl/md5.h>
@@ -43,34 +43,34 @@
 #define D2I_X509_CONST
 #endif
 
-#define SSL_RC4 RC4_KEY
-#define SSL_SHA1 SHA_CTX
-#define SSL_MD5 MD5_CTX
-#define SSL_CERT X509
-#define SSL_RKEY RSA
+#define RDSSL_RC4 RC4_KEY
+#define RDSSL_SHA1 SHA_CTX
+#define RDSSL_MD5 MD5_CTX
+#define RDSSL_CERT X509
+#define RDSSL_RKEY RSA
 
-void ssl_sha1_init(SSL_SHA1 * sha1);
-void ssl_sha1_update(SSL_SHA1 * sha1, uint8 * data, uint32 len);
-void ssl_sha1_final(SSL_SHA1 * sha1, uint8 * out_data);
-void ssl_md5_init(SSL_MD5 * md5);
-void ssl_md5_update(SSL_MD5 * md5, uint8 * data, uint32 len);
-void ssl_md5_final(SSL_MD5 * md5, uint8 * out_data);
-void ssl_rc4_set_key(SSL_RC4 * rc4, uint8 * key, uint32 len);
-void ssl_rc4_crypt(SSL_RC4 * rc4, uint8 * in_data, uint8 * out_data, uint32 len);
-void ssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
-		     uint8 * exponent);
-SSL_CERT *ssl_cert_read(uint8 * data, uint32 len);
-void ssl_cert_free(SSL_CERT * cert);
-SSL_RKEY *ssl_cert_to_rkey(SSL_CERT * cert, uint32 * key_len);
-RD_BOOL ssl_certs_ok(SSL_CERT * server_cert, SSL_CERT * cacert);
-int ssl_cert_print_fp(FILE * fp, SSL_CERT * cert);
-void ssl_rkey_free(SSL_RKEY * rkey);
-int ssl_rkey_get_exp_mod(SSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
-			 uint32 max_mod_len);
-RD_BOOL ssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
-		   uint8 * signature, uint32 sig_len);
+void rdssl_sha1_init(RDSSL_SHA1 * sha1);
+void rdssl_sha1_update(RDSSL_SHA1 * sha1, uint8 * data, uint32 len);
+void rdssl_sha1_final(RDSSL_SHA1 * sha1, uint8 * out_data);
+void rdssl_md5_init(RDSSL_MD5 * md5);
+void rdssl_md5_update(RDSSL_MD5 * md5, uint8 * data, uint32 len);
+void rdssl_md5_final(RDSSL_MD5 * md5, uint8 * out_data);
+void rdssl_rc4_set_key(RDSSL_RC4 * rc4, uint8 * key, uint32 len);
+void rdssl_rc4_crypt(RDSSL_RC4 * rc4, uint8 * in_data, uint8 * out_data, uint32 len);
+void rdssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
+		       uint8 * exponent);
+RDSSL_CERT *rdssl_cert_read(uint8 * data, uint32 len);
+void rdssl_cert_free(RDSSL_CERT * cert);
+RDSSL_RKEY *rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len);
+RD_BOOL rdssl_certs_ok(RDSSL_CERT * server_cert, RDSSL_CERT * cacert);
+int rdssl_cert_print_fp(FILE * fp, RDSSL_CERT * cert);
+void rdssl_rkey_free(RDSSL_RKEY * rkey);
+int rdssl_rkey_get_exp_mod(RDSSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
+			   uint32 max_mod_len);
+RD_BOOL rdssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
+		     uint8 * signature, uint32 sig_len);
 
-void ssl_hmac_md5(const void *key, int key_len,
-		  const unsigned char *msg, int msg_len, unsigned char *md);
+void rdssl_hmac_md5(const void *key, int key_len,
+		    const unsigned char *msg, int msg_len, unsigned char *md);
 
 #endif
diff --git a/src/VBox/RDP/client/tcp.c b/src/VBox/RDP/client-1.8.3/tcp.c
similarity index 61%
rename from src/VBox/RDP/client/tcp.c
rename to src/VBox/RDP/client-1.8.3/tcp.c
index 59e8ead..a88b56e 100644
--- a/src/VBox/RDP/client/tcp.c
+++ b/src/VBox/RDP/client-1.8.3/tcp.c
@@ -3,6 +3,7 @@
    Protocol services - TCP layer
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
    Copyright 2005-2011 Peter Astrand <astrand at cendio.se> for Cendio AB
+   Copyright 2012-2013 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -38,6 +39,10 @@
 #include <errno.h>		/* errno */
 #endif
 
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
 #include "rdesktop.h"
 
 #ifdef _WIN32
@@ -61,11 +66,17 @@
 #define STREAM_COUNT 1
 #endif
 
+static RD_BOOL g_ssl_initialized = False;
+static SSL *g_ssl = NULL;
+static SSL_CTX *g_ssl_ctx = NULL;
 static int g_sock;
+static RD_BOOL g_run_ui = False;
 static struct stream g_in;
 static struct stream g_out[STREAM_COUNT];
 int g_tcp_port_rdp = TCP_PORT_RDP;
 extern RD_BOOL g_user_quit;
+extern RD_BOOL g_network_error;
+extern RD_BOOL g_reconnect_loop;
 
 /* wait till socket is ready to write or timeout */
 static RD_BOOL
@@ -118,26 +129,62 @@ tcp_init(uint32 maxlen)
 void
 tcp_send(STREAM s)
 {
+	int ssl_err;
 	int length = s->end - s->data;
 	int sent, total = 0;
 
+	if (g_network_error == True)
+		return;
+
 #ifdef WITH_SCARD
 	scard_lock(SCARD_LOCK_TCP);
 #endif
 	while (total < length)
 	{
-		sent = send(g_sock, s->data + total, length - total, 0);
-		if (sent <= 0)
+		if (g_ssl)
 		{
-			if (sent == -1 && TCP_BLOCKS)
+			sent = SSL_write(g_ssl, s->data + total, length - total);
+			if (sent <= 0)
 			{
-				tcp_can_send(g_sock, 100);
-				sent = 0;
+				ssl_err = SSL_get_error(g_ssl, sent);
+				if (sent < 0 && (ssl_err == SSL_ERROR_WANT_READ ||
+						 ssl_err == SSL_ERROR_WANT_WRITE))
+				{
+					tcp_can_send(g_sock, 100);
+					sent = 0;
+				}
+				else
+				{
+#ifdef WITH_SCARD
+					scard_unlock(SCARD_LOCK_TCP);
+#endif
+
+					error("SSL_write: %d (%s)\n", ssl_err, TCP_STRERROR);
+					g_network_error = True;
+					return;
+				}
 			}
-			else
+		}
+		else
+		{
+			sent = send(g_sock, s->data + total, length - total, 0);
+			if (sent <= 0)
 			{
-				error("send: %s\n", TCP_STRERROR);
-				return;
+				if (sent == -1 && TCP_BLOCKS)
+				{
+					tcp_can_send(g_sock, 100);
+					sent = 0;
+				}
+				else
+				{
+#ifdef WITH_SCARD
+					scard_unlock(SCARD_LOCK_TCP);
+#endif
+
+					error("send: %s\n", TCP_STRERROR);
+					g_network_error = True;
+					return;
+				}
 			}
 		}
 		total += sent;
@@ -152,7 +199,10 @@ STREAM
 tcp_recv(STREAM s, uint32 length)
 {
 	uint32 new_length, end_offset, p_offset;
-	int rcvd = 0;
+	int rcvd = 0, ssl_err;
+
+	if (g_network_error == True)
+		return NULL;
 
 	if (s == NULL)
 	{
@@ -182,30 +232,67 @@ tcp_recv(STREAM s, uint32 length)
 
 	while (length > 0)
 	{
-		if (!ui_select(g_sock))
+		if ((!g_ssl || SSL_pending(g_ssl) <= 0) && g_run_ui)
 		{
-			/* User quit */
-			g_user_quit = True;
-			return NULL;
+			if (!ui_select(g_sock))
+			{
+				/* User quit */
+				g_user_quit = True;
+				return NULL;
+			}
 		}
 
-		rcvd = recv(g_sock, s->end, length, 0);
-		if (rcvd < 0)
+		if (g_ssl)
 		{
-			if (rcvd == -1 && TCP_BLOCKS)
+			rcvd = SSL_read(g_ssl, s->end, length);
+			ssl_err = SSL_get_error(g_ssl, rcvd);
+
+			if (ssl_err == SSL_ERROR_SSL)
+			{
+				if (SSL_get_shutdown(g_ssl) & SSL_RECEIVED_SHUTDOWN)
+				{
+					error("Remote peer initiated ssl shutdown.\n");
+					return NULL;
+				}
+
+				ERR_print_errors_fp(stdout);
+				g_network_error = True;
+				return NULL;
+			}
+
+			if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE)
 			{
 				rcvd = 0;
 			}
-			else
+			else if (ssl_err != SSL_ERROR_NONE)
 			{
-				error("recv: %s\n", TCP_STRERROR);
+				error("SSL_read: %d (%s)\n", ssl_err, TCP_STRERROR);
+				g_network_error = True;
 				return NULL;
 			}
+
 		}
-		else if (rcvd == 0)
+		else
 		{
-			error("Connection closed\n");
-			return NULL;
+			rcvd = recv(g_sock, s->end, length, 0);
+			if (rcvd < 0)
+			{
+				if (rcvd == -1 && TCP_BLOCKS)
+				{
+					rcvd = 0;
+				}
+				else
+				{
+					error("recv: %s\n", TCP_STRERROR);
+					g_network_error = True;
+					return NULL;
+				}
+			}
+			else if (rcvd == 0)
+			{
+				error("Connection closed\n");
+				return NULL;
+			}
 		}
 
 		s->end += rcvd;
@@ -215,6 +302,128 @@ tcp_recv(STREAM s, uint32 length)
 	return s;
 }
 
+/* Establish a SSL/TLS 1.0 connection */
+RD_BOOL
+tcp_tls_connect(void)
+{
+	int err;
+	long options;
+
+	if (!g_ssl_initialized)
+	{
+		SSL_load_error_strings();
+		SSL_library_init();
+		g_ssl_initialized = True;
+	}
+
+	/* create process context */
+	if (g_ssl_ctx == NULL)
+	{
+		g_ssl_ctx = SSL_CTX_new(TLSv1_client_method());
+		if (g_ssl_ctx == NULL)
+		{
+			error("tcp_tls_connect: SSL_CTX_new() failed to create TLS v1.0 context\n");
+			goto fail;
+		}
+
+		options = 0;
+#ifdef SSL_OP_NO_COMPRESSION
+		options |= SSL_OP_NO_COMPRESSION;
+#endif // __SSL_OP_NO_COMPRESSION
+		options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+		SSL_CTX_set_options(g_ssl_ctx, options);
+	}
+
+	/* free old connection */
+	if (g_ssl)
+		SSL_free(g_ssl);
+
+	/* create new ssl connection */
+	g_ssl = SSL_new(g_ssl_ctx);
+	if (g_ssl == NULL)
+	{
+		error("tcp_tls_connect: SSL_new() failed\n");
+		goto fail;
+	}
+
+	if (SSL_set_fd(g_ssl, g_sock) < 1)
+	{
+		error("tcp_tls_connect: SSL_set_fd() failed\n");
+		goto fail;
+	}
+
+	do
+	{
+		err = SSL_connect(g_ssl);
+	}
+	while (SSL_get_error(g_ssl, err) == SSL_ERROR_WANT_READ);
+
+	if (err < 0)
+	{
+		ERR_print_errors_fp(stdout);
+		goto fail;
+	}
+
+	return True;
+
+      fail:
+	if (g_ssl)
+		SSL_free(g_ssl);
+	if (g_ssl_ctx)
+		SSL_CTX_free(g_ssl_ctx);
+
+	g_ssl = NULL;
+	g_ssl_ctx = NULL;
+	return False;
+}
+
+/* Get public key from server of TLS 1.0 connection */
+RD_BOOL
+tcp_tls_get_server_pubkey(STREAM s)
+{
+	X509 *cert = NULL;
+	EVP_PKEY *pkey = NULL;
+
+	s->data = s->p = NULL;
+	s->size = 0;
+
+	if (g_ssl == NULL)
+		goto out;
+
+	cert = SSL_get_peer_certificate(g_ssl);
+	if (cert == NULL)
+	{
+		error("tcp_tls_get_server_pubkey: SSL_get_peer_certificate() failed\n");
+		goto out;
+	}
+
+	pkey = X509_get_pubkey(cert);
+	if (pkey == NULL)
+	{
+		error("tcp_tls_get_server_pubkey: X509_get_pubkey() failed\n");
+		goto out;
+	}
+
+	s->size = i2d_PublicKey(pkey, NULL);
+	if (s->size < 1)
+	{
+		error("tcp_tls_get_server_pubkey: i2d_PublicKey() failed\n");
+		goto out;
+	}
+
+	s->data = s->p = xmalloc(s->size);
+	i2d_PublicKey(pkey, &s->p);
+	s->p = s->data;
+	s->end = s->p + s->size;
+
+      out:
+	if (cert)
+		X509_free(cert);
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	return (s->size != 0);
+}
+
 /* Establish a connection on the TCP layer */
 RD_BOOL
 tcp_connect(char *server)
@@ -289,8 +498,11 @@ tcp_connect(char *server)
 
 	if (connect(g_sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
 	{
-		error("connect: %s\n", TCP_STRERROR);
+		if (!g_reconnect_loop)
+			error("connect: %s\n", TCP_STRERROR);
+
 		TCP_CLOSE(g_sock);
+		g_sock = -1;
 		return False;
 	}
 
@@ -327,7 +539,18 @@ tcp_connect(char *server)
 void
 tcp_disconnect(void)
 {
+	if (g_ssl)
+	{
+		if (!g_network_error)
+			(void) SSL_shutdown(g_ssl);
+		SSL_free(g_ssl);
+		g_ssl = NULL;
+		SSL_CTX_free(g_ssl_ctx);
+		g_ssl_ctx = NULL;
+	}
+
 	TCP_CLOSE(g_sock);
+	g_sock = -1;
 }
 
 char *
@@ -346,6 +569,16 @@ tcp_get_address()
 	return ipaddr;
 }
 
+RD_BOOL
+tcp_is_connected()
+{
+	struct sockaddr_in sockaddr;
+	socklen_t len = sizeof(sockaddr);
+	if (getpeername(g_sock, (struct sockaddr *) &sockaddr, &len))
+		return True;
+	return False;
+}
+
 /* reset the state of the tcp layer */
 /* Support for Session Directory */
 void
@@ -353,8 +586,6 @@ tcp_reset_state(void)
 {
 	int i;
 
-	g_sock = -1;		/* reset socket */
-
 	/* Clear the incoming stream */
 	if (g_in.data != NULL)
 		xfree(g_in.data);
@@ -384,3 +615,9 @@ tcp_reset_state(void)
 		g_out[i].channel_hdr = NULL;
 	}
 }
+
+void
+tcp_run_ui(RD_BOOL run)
+{
+	g_run_ui = run;
+}
diff --git a/src/VBox/RDP/client/types.h b/src/VBox/RDP/client-1.8.3/types.h
similarity index 93%
rename from src/VBox/RDP/client/types.h
rename to src/VBox/RDP/client-1.8.3/types.h
index 2db5808..bfdb44f 100644
--- a/src/VBox/RDP/client/types.h
+++ b/src/VBox/RDP/client-1.8.3/types.h
@@ -2,6 +2,7 @@
    rdesktop: A Remote Desktop Protocol client.
    Common data types
    Copyright (C) Matthew Chapman 1999-2008
+   Copyright 2014 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -45,6 +46,15 @@ typedef void *RD_HGLYPH;
 typedef void *RD_HCOLOURMAP;
 typedef void *RD_HCURSOR;
 
+
+typedef enum _RDP_VERSION
+{
+	RDP_V4 = 4,
+	RDP_V5 = 5,
+	RDP_V6 = 6
+} RDP_VERSION;
+
+
 typedef struct _RD_POINT
 {
 	sint16 x, y;
@@ -136,6 +146,16 @@ typedef struct _key_translation
 }
 key_translation;
 
+typedef struct _key_translation_entry
+{
+	key_translation *tr;
+	/* The full KeySym for this entry, not KEYMAP_MASKed */
+	uint32 keysym;
+	/* This will be non-NULL if there has been a hash collision */
+	struct _key_translation_entry *next;
+}
+key_translation_entry;
+
 typedef struct _VCHANNEL
 {
 	uint16 mcs_id;
diff --git a/src/VBox/RDP/client-1.8.3/utils.c b/src/VBox/RDP/client-1.8.3/utils.c
new file mode 100644
index 0000000..35cf718
--- /dev/null
+++ b/src/VBox/RDP/client-1.8.3/utils.c
@@ -0,0 +1,233 @@
+/* -*- c-basic-offset: 8 -*-
+   rdesktop: A Remote Desktop Protocol client.
+   Generic utility functions
+   Copyright 2013 Henrik Andersson <hean01 at cendio.se> for Cendio AB
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the General Public License version 2 (GPLv2) at this time for any software where
+ * a choice of GPL license versions is made available with the language indicating
+ * that GPLv2 or any later version may be used, or where a choice of which version
+ * of the GPL is applied is otherwise unspecified.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#include "rdesktop.h"
+
+
+#ifdef HAVE_ICONV
+extern char g_codepage[16];
+static RD_BOOL g_iconv_works = True;
+#endif
+
+
+
+char *
+utils_string_escape(const char *str)
+{
+	const char *p;
+	char *pe, *e, esc[4];
+	size_t es;
+	int cnt;
+
+	/* count indices */
+	cnt = 0;
+	p = str;
+	while (*(p++) != '\0')
+		if ((unsigned char) *p < 32 || *p == '%')
+			cnt++;
+
+	/* if no characters needs escaping return copy of str */
+	if (cnt == 0)
+		return strdup(str);
+
+	/* allocate new mem for result */
+	es = strlen(str) + (cnt * 3) + 1;
+	pe = e = xmalloc(es);
+	memset(e, 0, es);
+	p = str;
+	while (*p != '\0')
+	{
+		if ((unsigned char) *p < 32 || *p == '%')
+		{
+			snprintf(esc, 4, "%%%02X", *p);
+			memcpy(pe, esc, 3);
+			pe += 3;
+		}
+		else
+		{
+			*pe = *p;
+			pe++;
+		}
+
+		p++;
+	}
+
+	return e;
+}
+
+char *
+utils_string_unescape(const char *str)
+{
+	char *ns, *ps, *pd, c;
+
+	ns = xmalloc(strlen(str) + 1);
+	memcpy(ns, str, strlen(str) + 1);
+	ps = pd = ns;
+
+	while (*ps != '\0')
+	{
+		/* check if found escaped character */
+		if (ps[0] == '%')
+		{
+			if (sscanf(ps, "%%%2hhX", &c) == 1)
+			{
+				pd[0] = c;
+				ps += 3;
+				pd++;
+				continue;
+			}
+		}
+
+		/* just copy over the char */
+		*pd = *ps;
+		ps++;
+		pd++;
+	}
+	pd[0] = '\0';
+
+	return ns;
+}
+
+int
+utils_mkdir_safe(const char *path, int mask)
+{
+	int res = 0;
+	struct stat st;
+
+	res = stat(path, &st);
+	if (res == -1)
+		return mkdir(path, mask);
+
+	if (!S_ISDIR(st.st_mode))
+	{
+		errno = EEXIST;
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+utils_mkdir_p(const char *path, int mask)
+{
+	int res;
+	char *ptok;
+	char pt[PATH_MAX];
+	char bp[PATH_MAX];
+
+	if (!path || strlen(path) == 0)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (strlen(path) > PATH_MAX)
+	{
+		errno = E2BIG;
+		return -1;
+	}
+
+	res = 0;
+	pt[0] = bp[0] = '\0';
+	strcpy(bp, path);
+
+	ptok = strtok(bp, "/");
+	if (ptok == NULL)
+		return utils_mkdir_safe(path, mask);
+
+	do
+	{
+		if (ptok != bp)
+			strcat(pt, "/");
+
+		strcat(pt, ptok);
+		res = utils_mkdir_safe(pt, mask);
+		if (res != 0)
+			return res;
+
+	}
+	while ((ptok = strtok(NULL, "/")) != NULL);
+
+	return 0;
+}
+
+/* Convert from system locale string to utf-8 */
+int
+utils_locale_to_utf8(const char *src, size_t is, char *dest, size_t os)
+{
+#ifdef HAVE_ICONV
+	static iconv_t *iconv_h = (iconv_t) - 1;
+	if (strncmp(g_codepage, "UTF-8", strlen("UTF-8")) == 0)
+		goto pass_trough_as_is;
+
+	if (g_iconv_works == False)
+		goto pass_trough_as_is;
+
+	/* if not already initialize */
+	if (iconv_h == (iconv_t) - 1)
+	{
+		if ((iconv_h = iconv_open("UTF-8", g_codepage)) == (iconv_t) - 1)
+		{
+			warning("utils_string_to_utf8: iconv_open[%s -> %s] fail %p\n",
+				g_codepage, "UTF-8", iconv_h);
+
+			g_iconv_works = False;
+			goto pass_trough_as_is;
+		}
+	}
+
+	/* convert string */
+	if (iconv(iconv_h, (ICONV_CONST char **) &src, &is, &dest, &os) == (size_t) - 1)
+	{
+		iconv_close(iconv_h);
+		iconv_h = (iconv_t) - 1;
+		warning("utils_string_to_utf8: iconv(1) fail, errno %d\n", errno);
+
+		g_iconv_works = False;
+		goto pass_trough_as_is;
+	}
+
+	/* Out couldn't hold the entire convertion */
+	if (is != 0)
+		return -1;
+
+#endif
+      pass_trough_as_is:
+	/* can dest hold strcpy of src */
+	if (os < (strlen(src) + 1))
+		return -1;
+
+	memcpy(dest, src, strlen(src) + 1);
+	return 0;
+}
diff --git a/src/VBox/RDP/client/vrdp/rdpusb.c b/src/VBox/RDP/client-1.8.3/vrdp/rdpusb.c
similarity index 100%
rename from src/VBox/RDP/client/vrdp/rdpusb.c
rename to src/VBox/RDP/client-1.8.3/vrdp/rdpusb.c
diff --git a/src/VBox/RDP/client/vrdp/vrdpusb.h b/src/VBox/RDP/client-1.8.3/vrdp/vrdpusb.h
similarity index 100%
rename from src/VBox/RDP/client/vrdp/vrdpusb.h
rename to src/VBox/RDP/client-1.8.3/vrdp/vrdpusb.h
diff --git a/src/VBox/RDP/client/xclip.c b/src/VBox/RDP/client-1.8.3/xclip.c
similarity index 99%
rename from src/VBox/RDP/client/xclip.c
rename to src/VBox/RDP/client-1.8.3/xclip.c
index 9ecf418..a521788 100644
--- a/src/VBox/RDP/client/xclip.c
+++ b/src/VBox/RDP/client-1.8.3/xclip.c
@@ -1,7 +1,7 @@
 /* -*- c-basic-offset: 8 -*-
    rdesktop: A Remote Desktop Protocol client.
    Protocol services - Clipboard functions
-   Copyright (C) Erik Forsberg <forsberg at cendio.se> 2003-2008
+   Copyright 2003-2008 Erik Forsberg <forsberg at cendio.se> for Cendio AB
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
    Copyright 2006-2011 Pierre Ossman <ossman at cendio.se> for Cendio AB
 
@@ -416,7 +416,7 @@ xclip_send_data_with_convert(uint8 * source, size_t source_size, Atom target)
 		translated_data = lf2crlf(source, &length);
 		if (translated_data != NULL)
 		{
-			helper_cliprdr_send_response(translated_data, length);
+			helper_cliprdr_send_response(translated_data, length + 1);
 			xfree(translated_data);	/* Not the same thing as XFree! */
 		}
 
diff --git a/src/VBox/RDP/client/xkeymap.c b/src/VBox/RDP/client-1.8.3/xkeymap.c
similarity index 89%
rename from src/VBox/RDP/client/xkeymap.c
rename to src/VBox/RDP/client-1.8.3/xkeymap.c
index 04813f8..9134c66 100644
--- a/src/VBox/RDP/client/xkeymap.c
+++ b/src/VBox/RDP/client-1.8.3/xkeymap.c
@@ -3,7 +3,8 @@
    User interface services - X keyboard mapping
 
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
-   Copyright (C) 2003-2008 Peter Astrand <astrand at cendio.se> for Cendio AB
+   Copyright 2003-2008 Peter Astrand <astrand at cendio.se> for Cendio AB
+   Copyright 2014 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -43,8 +44,8 @@
 #include "rdesktop.h"
 #include "scancodes.h"
 
-#define KEYMAP_SIZE 0xffff+1
-#define KEYMAP_MASK 0xffff
+#define KEYMAP_SIZE 0x7f+1
+#define KEYMAP_MASK 0x7f
 #define KEYMAP_MAX_LINE_LENGTH 80
 
 extern Display *g_display;
@@ -56,11 +57,11 @@ extern int g_keyboard_subtype;
 extern int g_keyboard_functionkeys;
 extern int g_win_button_size;
 extern RD_BOOL g_enable_compose;
-extern RD_BOOL g_use_rdp5;
+extern RDP_VERSION g_rdp_version;
 extern RD_BOOL g_numlock_sync;
 
 static RD_BOOL keymap_loaded;
-static key_translation *keymap[KEYMAP_SIZE];
+static key_translation_entry *keymap[KEYMAP_SIZE];
 static KeySym keypress_keysyms[256];
 static int min_keycode;
 static uint16 remote_modifier_state = 0;
@@ -82,11 +83,93 @@ free_key_translation(key_translation * ptr)
 	}
 }
 
+/* Free the key_translation_entry for a given keysym and remove from the table */
+static void
+delete_key_translation_entry(KeySym keysym)
+{
+	uint32 hash;
+	key_translation_entry *ptr;
+	key_translation_entry *next;
+	key_translation_entry *prev;
+	key_translation_entry tmp;
+
+	/* Faking a prev node allows us to keep the algorithm simple */
+	hash = keysym & KEYMAP_MASK;
+	ptr = keymap[hash];
+	tmp.next = ptr;
+	prev = &tmp;
+
+	while (ptr)
+	{
+		next = ptr->next;
+		if (ptr->keysym == keysym)
+		{
+			free_key_translation(ptr->tr);
+			prev->next = next;
+			xfree(ptr);
+		}
+		else
+		{
+			prev = ptr;
+		}
+
+		ptr = next;
+	}
+
+	/* Copy pointer back from our fake node */
+	keymap[hash] = tmp.next;
+}
+
+/* Allocate and return a new entry in the translation table */
+static key_translation_entry *
+new_key_translation_entry(KeySym keysym)
+{
+	uint32 hash;
+	key_translation_entry *entry;
+
+	/* Clear out any existing entry */
+	delete_key_translation_entry(keysym);
+
+	/* Allocate the new one */
+	entry = (key_translation_entry *) xmalloc(sizeof(key_translation_entry));
+	memset(entry, 0, sizeof(key_translation_entry));
+	entry->keysym = keysym;
+
+	/* And insert it at head of list */
+	hash = keysym & KEYMAP_MASK;
+	entry->next = keymap[hash];
+	keymap[hash] = entry;
+
+	return entry;
+}
+
+/* Retrieve the key_translation_entry for a given keysym */
+static key_translation_entry *
+get_key_translation_entry(uint32 keysym)
+{
+	key_translation_entry *ptr;
+	key_translation_entry *next;
+
+	ptr = keymap[keysym & KEYMAP_MASK];
+
+	while (ptr)
+	{
+		next = ptr->next;
+		if (ptr->keysym == keysym)
+			return ptr;
+
+		ptr = next;
+	}
+
+	/* Not found */
+	return NULL;
+}
+
 static void
 add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)
 {
 	KeySym keysym;
-	key_translation *tr;
+	key_translation_entry *entry;
 
 	keysym = XStringToKeysym(keyname);
 	if (keysym == NoSymbol)
@@ -98,12 +181,14 @@ add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)
 	DEBUG_KBD(("Adding translation, keysym=0x%x, scancode=0x%x, "
 		   "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers));
 
-	tr = (key_translation *) xmalloc(sizeof(key_translation));
-	memset(tr, 0, sizeof(key_translation));
-	tr->scancode = scancode;
-	tr->modifiers = modifiers;
-	free_key_translation(keymap[keysym & KEYMAP_MASK]);
-	keymap[keysym & KEYMAP_MASK] = tr;
+	/* Make a new entry in the table */
+	entry = new_key_translation_entry(keysym);
+
+	/* And add the new translation to it */
+	entry->tr = (key_translation *) xmalloc(sizeof(key_translation));
+	memset(entry->tr, 0, sizeof(key_translation));
+	entry->tr->scancode = scancode;
+	entry->tr->modifiers = modifiers;
 
 	return;
 }
@@ -112,6 +197,8 @@ static void
 add_sequence(char *rest, char *mapname)
 {
 	KeySym keysym;
+	KeySym seq_keysym;
+	key_translation_entry *entry;
 	key_translation *tr, **prev_next;
 	size_t chars;
 	char keyname[KEYMAP_MAX_LINE_LENGTH];
@@ -132,11 +219,10 @@ add_sequence(char *rest, char *mapname)
 		return;
 	}
 
-
 	DEBUG_KBD(("Adding sequence for keysym (0x%lx, %s) -> ", keysym, keyname));
 
-	free_key_translation(keymap[keysym & KEYMAP_MASK]);
-	prev_next = &keymap[keysym & KEYMAP_MASK];
+	entry = new_key_translation_entry(keysym);
+	prev_next = &(entry->tr);
 
 	while (*rest)
 	{
@@ -149,22 +235,32 @@ add_sequence(char *rest, char *mapname)
 		STRNCPY(keyname, rest, chars + 1);
 		rest += chars;
 
-		keysym = XStringToKeysym(keyname);
-		if (keysym == NoSymbol)
+		/* Handle trailing whitespace */
+		if (*keyname == 0)
+			break;
+
+		seq_keysym = XStringToKeysym(keyname);
+		if (seq_keysym == NoSymbol)
 		{
 			DEBUG_KBD(("Bad keysym \"%s\" in keymap %s (ignoring line)\n", keyname,
 				   mapname));
+			delete_key_translation_entry(keysym);
 			return;
 		}
 
 		/* Allocate space for key_translation structure */
 		tr = (key_translation *) xmalloc(sizeof(key_translation));
 		memset(tr, 0, sizeof(key_translation));
+
+		/* Do this straight away so the key_translation won't get orphaned on error */
+		if (!entry->tr)
+			entry->tr = tr;
+
 		*prev_next = tr;
 		prev_next = &tr->next;
-		tr->seq_keysym = keysym;
+		tr->seq_keysym = seq_keysym;
 
-		DEBUG_KBD(("0x%x, ", (unsigned int) keysym));
+		DEBUG_KBD(("0x%x, ", (unsigned int) seq_keysym));
 	}
 	DEBUG_KBD(("\n"));
 }
@@ -476,7 +572,7 @@ send_winkey(uint32 ev_time, RD_BOOL pressed, RD_BOOL leftkey)
 
 	if (pressed)
 	{
-		if (g_use_rdp5)
+		if (g_rdp_version >= RDP_V5)
 		{
 			rdp_send_scancode(ev_time, RDP_KEYPRESS, winkey);
 		}
@@ -490,7 +586,7 @@ send_winkey(uint32 ev_time, RD_BOOL pressed, RD_BOOL leftkey)
 	else
 	{
 		/* key released */
-		if (g_use_rdp5)
+		if (g_rdp_version >= RDP_V5)
 		{
 			rdp_send_scancode(ev_time, RDP_KEYRELEASE, winkey);
 		}
@@ -505,7 +601,7 @@ send_winkey(uint32 ev_time, RD_BOOL pressed, RD_BOOL leftkey)
 static void
 reset_winkey(uint32 ev_time)
 {
-	if (g_use_rdp5)
+	if (g_rdp_version >= RDP_V5)
 	{
 		/* For some reason, it seems to suffice to release
 		 *either* the left or right winkey. */
@@ -699,8 +795,11 @@ xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
 {
 	key_translation tr = { 0, 0, 0, 0 };
 	key_translation *ptr;
+	key_translation_entry *entry;
+
+	entry = get_key_translation_entry(keysym);
+	ptr = entry ? entry->tr : NULL;
 
-	ptr = keymap[keysym & KEYMAP_MASK];
 	if (ptr)
 	{
 		tr = *ptr;
diff --git a/src/VBox/RDP/client/xproto.h b/src/VBox/RDP/client-1.8.3/xproto.h
similarity index 95%
rename from src/VBox/RDP/client/xproto.h
rename to src/VBox/RDP/client-1.8.3/xproto.h
index 7d70140..e3c07a5 100644
--- a/src/VBox/RDP/client/xproto.h
+++ b/src/VBox/RDP/client-1.8.3/xproto.h
@@ -12,5 +12,6 @@ int ewmh_set_window_modal(Window wnd);
 void ewmh_set_icon(Window wnd, int width, int height, const char *rgba_data);
 void ewmh_del_icon(Window wnd, int width, int height);
 int ewmh_set_window_above(Window wnd);
+RD_BOOL ewmh_is_window_above(Window w);
 void set_keypress_keysym(unsigned int keycode, KeySym keysym);
 KeySym reset_keypress_keysym(unsigned int keycode, KeySym keysym);
diff --git a/src/VBox/RDP/client/xwin.c b/src/VBox/RDP/client-1.8.3/xwin.c
similarity index 98%
rename from src/VBox/RDP/client/xwin.c
rename to src/VBox/RDP/client-1.8.3/xwin.c
index a4d612e..067f07c 100644
--- a/src/VBox/RDP/client/xwin.c
+++ b/src/VBox/RDP/client-1.8.3/xwin.c
@@ -4,6 +4,7 @@
    Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
    Copyright 2007-2008 Pierre Ossman <ossman at cendio.se> for Cendio AB
    Copyright 2002-2011 Peter Astrand <astrand at cendio.se> for Cendio AB
+   Copyright 2012-2013 Henrik Andersson <hean01 at cendio.se> for Cendio AB
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -54,6 +55,7 @@ extern RD_BOOL g_grab_keyboard;
 extern RD_BOOL g_hide_decorations;
 extern RD_BOOL g_pending_resize;
 extern char g_title[];
+extern char g_seamless_spawn_cmd[];
 /* Color depth of the RDP session.
    As of RDP 5.1, it may be 8, 15, 16 or 24. */
 extern int g_server_depth;
@@ -102,6 +104,7 @@ static RD_BOOL g_seamless_active = False;	/* We are currently in seamless mode *
 static RD_BOOL g_seamless_hidden = False;	/* Desktop is hidden on server */
 static RD_BOOL g_seamless_broken_restack = False;	/* WM does not properly restack */
 extern RD_BOOL g_seamless_rdp;
+extern RD_BOOL g_seamless_persistent_mode;
 
 extern uint32 g_embed_wnd;
 RD_BOOL g_enable_compose = False;
@@ -581,14 +584,14 @@ sw_wait_configurenotify(Window wnd, unsigned long serial)
 	XEvent xevent;
 	sw_configurenotify_context context;
 	struct timeval now;
-	struct timeval nextsecond;
+	struct timeval future;
 	RD_BOOL got = False;
 
 	context.window = wnd;
 	context.serial = serial;
 
-	gettimeofday(&nextsecond, NULL);
-	nextsecond.tv_sec += 1;
+	gettimeofday(&future, NULL);
+	future.tv_usec += 500000;
 
 	do
 	{
@@ -600,7 +603,7 @@ sw_wait_configurenotify(Window wnd, unsigned long serial)
 		usleep(100000);
 		gettimeofday(&now, NULL);
 	}
-	while (timercmp(&now, &nextsecond, <));
+	while (timercmp(&now, &future, <));
 
 	if (!got)
 	{
@@ -782,7 +785,14 @@ seamless_restack_test()
 
 	/* Destroy windows */
 	for (i = 0; i < 3; i++)
+	{
 		XDestroyWindow(g_display, wnds[i]);
+		do
+		{
+			XWindowEvent(g_display, wnds[i], StructureNotifyMask, &xevent);
+		}
+		while (xevent.type != DestroyNotify);
+	}
 }
 
 #define SPLITCOLOUR15(colour, rv) \
@@ -2121,6 +2131,7 @@ ui_create_window(void)
 
 	if (g_seamless_rdp)
 	{
+		seamless_reset_state();
 		seamless_restack_test();
 	}
 
@@ -2160,6 +2171,12 @@ ui_resize_window()
 	}
 }
 
+RD_BOOL
+ui_have_window()
+{
+	return g_wnd ? True : False;
+}
+
 void
 ui_destroy_window(void)
 {
@@ -2279,6 +2296,14 @@ handle_button_event(XEvent xevent, RD_BOOL down)
 		}
 	}
 
+	/* Ignore mouse scroll button release event which will be handled as an additional
+	 * scrolldown event on the Windows side.
+	 */
+	if (!down && (button == MOUSE_FLAG_BUTTON4 || button == MOUSE_FLAG_BUTTON5))
+	{
+		return;
+	}
+
 	if (xevent.xmotion.window == g_wnd)
 	{
 		rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
@@ -2684,6 +2709,9 @@ ui_select(int rdp_socket)
 		rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
 		seamless_select_timeout(&tv);
 
+		/* add ctrl slaves handles */
+		ctrl_add_fds(&n, &rfds);
+
 		n++;
 
 		switch (select(n, &rfds, &wfds, NULL, &tv))
@@ -2712,6 +2740,8 @@ ui_select(int rdp_socket)
 
 		rdpdr_check_fds(&rfds, &wfds, (RD_BOOL) False);
 
+		ctrl_check_fds(&rfds, &wfds);
+
 		if (FD_ISSET(rdp_socket, &rfds))
 			return 1;
 
@@ -3819,6 +3849,14 @@ ui_seamless_begin(RD_BOOL hidden)
 
 	if (!hidden)
 		ui_seamless_toggle();
+
+	if (g_seamless_spawn_cmd[0])
+	{
+		seamless_send_spawn(g_seamless_spawn_cmd);
+		g_seamless_spawn_cmd[0] = 0;
+	}
+
+	seamless_send_persistent(g_seamless_persistent_mode);
 }
 
 
@@ -4177,20 +4215,21 @@ ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, u
 		/* X11 windows must be at least 1x1 */
 		return;
 
-	sw->xoffset = x;
-	sw->yoffset = y;
-	sw->width = width;
-	sw->height = height;
-
 	/* If we move the window in a maximized state, then KDE won't
 	   accept restoration */
 	switch (sw->state)
 	{
 		case SEAMLESSRDP_MINIMIZED:
 		case SEAMLESSRDP_MAXIMIZED:
+			sw_update_position(sw);
 			return;
 	}
 
+	sw->xoffset = x;
+	sw->yoffset = y;
+	sw->width = width;
+	sw->height = height;
+
 	/* FIXME: Perhaps use ewmh_net_moveresize_window instead */
 	XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);
 }
@@ -4202,6 +4241,7 @@ ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long
 	seamless_window *sw;
 	XWindowChanges values;
 	unsigned long restack_serial;
+	unsigned int value_mask;
 
 	if (!g_seamless_active)
 		return;
@@ -4224,25 +4264,43 @@ ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long
 			return;
 		}
 
-		if (!g_seamless_broken_restack)
+		values.stack_mode = Below;
+		value_mask = CWStackMode | CWSibling;
+		values.sibling = sw_behind->wnd;
+
+		/* Avoid that topmost windows references non-topmost
+		   windows, and vice versa. */
+		if (ewmh_is_window_above(sw->wnd))
+		{
+			if (!ewmh_is_window_above(sw_behind->wnd))
+			{
+				/* Disallow, move to bottom of the
+				   topmost stack. */
+				values.stack_mode = Below;
+				value_mask = CWStackMode;	/* Not sibling */
+			}
+		}
+		else
 		{
-			values.stack_mode = Below;
-			values.sibling = sw_behind->wnd;
-			restack_serial = XNextRequest(g_display);
-			XReconfigureWMWindow(g_display, sw->wnd, DefaultScreen(g_display),
-					     CWStackMode | CWSibling, &values);
-			sw_wait_configurenotify(sw->wnd, restack_serial);
+			if (ewmh_is_window_above(sw_behind->wnd))
+			{
+				/* Move to top of non-topmost
+				   stack. */
+				values.stack_mode = Above;
+				value_mask = CWStackMode;	/* Not sibling */
+			}
 		}
 	}
 	else
 	{
 		values.stack_mode = Above;
-		restack_serial = XNextRequest(g_display);
-		XReconfigureWMWindow(g_display, sw->wnd, DefaultScreen(g_display), CWStackMode,
-				     &values);
-		sw_wait_configurenotify(sw->wnd, restack_serial);
+		value_mask = CWStackMode;
 	}
 
+	restack_serial = XNextRequest(g_display);
+	XReconfigureWMWindow(g_display, sw->wnd, DefaultScreen(g_display), value_mask, &values);
+	sw_wait_configurenotify(sw->wnd, restack_serial);
+
 	sw_restack_window(sw, behind);
 
 	if (flags & SEAMLESSRDP_CREATE_TOPMOST)
diff --git a/src/VBox/RDP/client/keymaps/cs b/src/VBox/RDP/client/keymaps/cs
deleted file mode 100644
index 5c89b00..0000000
--- a/src/VBox/RDP/client/keymaps/cs
+++ /dev/null
@@ -1,87 +0,0 @@
-# Czech keymap
-include common
-map 0x405
-
-# AltGr
-ISO_Level3_Shift 0xb8
-
-#
-# Top row
-#
-
-# `
-grave 0x29
-asciitilde 0x29 shift
-# 1
-exclam 0x2 shift
-# 2
-at 0x3 shift
-ecaron 0x3 altgr
-# 3
-numbersign 0x4 shift
-# 4
-dollar 0x5 shift
-# 5
-percent 0x6 shift
-# 6
-asciicircum 0x7 shift
-# 7
-ampersand 0x8 shift
-# 8
-asterisk 0x9 shift
-# 9
-parenleft 0xa shift
-# 0
-parenright 0xb shift
-# -
-minus 0xc
-underscore 0xc shift
-# =
-equal 0xd
-plus 0xd shift
-
-
-#
-# QWERTZ first row
-#
-
-# q
-q 0x10 altgr
-# e
-e 0x12 altgr
-# [
-bracketleft 0x1a
-braceleft 0x1a shift
-# ]
-bracketright 0x1b
-braceright 0x1b shift
-
-#
-# QWERTZ second row
-#
-
-# ;
-semicolon 0x27
-# ;
-colon 0x27 shift
-# '
-apostrophe 0x28
-# '
-quotedbl 0x28 shift
-
-#
-# QWERTZ third row
-#
-
-# v
-v 0x2f altgr
-# ,
-comma 0x33
-less 0x33 shift
-# .
-period 0x34
-greater 0x34 shift
-# /
-slash 0x35
-question 0x35 shift
-
diff --git a/src/VBox/Runtime/Makefile.kmk b/src/VBox/Runtime/Makefile.kmk
index efdabcd..7f50d2b 100644
--- a/src/VBox/Runtime/Makefile.kmk
+++ b/src/VBox/Runtime/Makefile.kmk
@@ -654,6 +654,8 @@ RuntimeR3_SOURCES.x86 += \
 	common/asm/ASMAtomicUoOrU32.asm \
 	common/asm/ASMRdMsrEx.asm \
 	common/asm/ASMWrMsrEx.asm \
+	common/asm/ASMGetXcr0.asm \
+	common/asm/ASMSetXcr0.asm \
 	common/math/bignum-amd64-x86.asm
 RuntimeR3_SOURCES.amd64 += \
 	common/asm/ASMCpuIdExSlow.asm \
@@ -665,6 +667,8 @@ RuntimeR3_SOURCES.amd64 += \
 	common/asm/ASMAtomicUoOrU32.asm \
 	common/asm/ASMRdMsrEx.asm \
 	common/asm/ASMWrMsrEx.asm \
+	common/asm/ASMGetXcr0.asm \
+	common/asm/ASMSetXcr0.asm \
 	common/math/bignum-amd64-x86.asm \
 	common/math/RTUInt128MulByU64.asm
 
@@ -1025,6 +1029,7 @@ RuntimeR3_SOURCES.freebsd = \
 	generic/RTProcIsRunningByName-generic.cpp \
 	generic/RTThreadGetNativeState-generic.cpp \
 	r3/freebsd/mp-freebsd.cpp \
+	r3/freebsd/systemmem-freebsd.cpp \
 	r3/freebsd/rtProcInitExePath-freebsd.cpp \
 	r3/generic/allocex-r3-generic.cpp \
 	r3/posix/RTFileQueryFsSizes-posix.cpp \
@@ -1032,7 +1037,6 @@ RuntimeR3_SOURCES.freebsd = \
 	r3/posix/RTMemProtect-posix.cpp \
 	r3/posix/RTPathUserHome-posix.cpp \
 	r3/posix/RTSystemQueryOSInfo-posix.cpp \
-	r3/posix/RTSystemQueryTotalRam-posix.cpp \
 	r3/posix/RTTimeNow-posix.cpp \
 	r3/posix/RTTimeSet-posix.cpp \
 	r3/posix/dir-posix.cpp \
@@ -1693,6 +1697,8 @@ RuntimeR0_SOURCES.x86 += \
 	common/asm/ASMAtomicUoIncU32.asm \
 	common/asm/ASMAtomicUoOrU64.asm \
 	common/asm/ASMAtomicUoOrU32.asm \
+	common/asm/ASMGetXcr0.asm \
+	common/asm/ASMSetXcr0.asm \
 	common/asm/ASMRdMsrEx.asm \
 	common/asm/ASMWrMsrEx.asm
 RuntimeR0_SOURCES.amd64 += \
@@ -1703,6 +1709,8 @@ RuntimeR0_SOURCES.amd64 += \
 	common/asm/ASMAtomicUoIncU32.asm \
 	common/asm/ASMAtomicUoOrU64.asm \
 	common/asm/ASMAtomicUoOrU32.asm \
+	common/asm/ASMGetXcr0.asm \
+	common/asm/ASMSetXcr0.asm \
 	common/asm/ASMRdMsrEx.asm \
 	common/asm/ASMWrMsrEx.asm
 
diff --git a/src/VBox/Runtime/VBox/VBoxRTDeps.cpp b/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
index 36090f8..e0fc16c 100644
--- a/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
+++ b/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
@@ -69,6 +69,7 @@ PFNRT g_VBoxRTDeps[] =
     (PFNRT)X509_verify_cert_error_string,
     (PFNRT)i2d_X509,
     (PFNRT)i2d_X509,
+    (PFNRT)i2d_PublicKey,
     (PFNRT)RSA_generate_key,
     (PFNRT)RSA_generate_key_ex,
     (PFNRT)DH_generate_parameters,
diff --git a/src/VBox/Runtime/common/alloc/memcache.cpp b/src/VBox/Runtime/common/alloc/memcache.cpp
index 43285e6..3b60576 100644
--- a/src/VBox/Runtime/common/alloc/memcache.cpp
+++ b/src/VBox/Runtime/common/alloc/memcache.cpp
@@ -86,7 +86,7 @@ typedef struct RTMEMCACHEPAGE
     void volatile              *pbmAlloc;
     /** Bitmap tracking which blocks that has been thru the constructor. */
     void volatile              *pbmCtor;
-    /** Pointer to the object array.. */
+    /** Pointer to the object array. */
     uint8_t                    *pbObjects;
     /** The number of objects on this page.  */
     uint32_t                    cObjects;
@@ -149,6 +149,11 @@ typedef struct RTMEMCACHEINT
 } RTMEMCACHEINT;
 
 
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static void rtMemCacheFreeList(RTMEMCACHEINT *pThis, PRTMEMCACHEFREEOBJ pHead);
+
 
 RTDECL(int) RTMemCacheCreate(PRTMEMCACHE phMemCache, size_t cbObject, size_t cbAlignment, uint32_t cMaxObjects,
                              PFNMEMCACHECTOR pfnCtor, PFNMEMCACHEDTOR pfnDtor, void *pvUser, uint32_t fFlags)
@@ -220,21 +225,6 @@ RTDECL(int) RTMemCacheCreate(PRTMEMCACHE phMemCache, size_t cbObject, size_t cbA
     pThis->pPageHint        = NULL;
     pThis->pFreeTop         = NULL;
 
-    /** @todo
-     * Here is a puzzler (or maybe I'm just blind), the free list code breaks
-     * badly on my macbook pro (i7) (32-bit).
-     *
-     * I tried changing the reads from unordered to ordered to no avail.  Then I
-     * tried optimizing the code with the ASMAtomicCmpXchgExPtr function to
-     * avoid some reads - no change. Inserting pause instructions did nothing
-     * (as expected).  The only thing which seems to make a difference is
-     * reading the pFreeTop pointer twice in the free code... This is weird or I'm
-     * overlooking something..
-     *
-     * No time to figure it out, so I'm disabling the broken code paths for
-     * now. */
-    pThis->fUseFreeList = false;
-
     *phMemCache = pThis;
     return VINF_SUCCESS;
 }
@@ -359,13 +349,14 @@ static int rtMemCacheGrow(RTMEMCACHEINT *pThis)
  */
 DECL_FORCE_INLINE(int32_t) rtMemCacheGrabObj(PRTMEMCACHEPAGE pPage)
 {
-    int32_t cFreeNew = ASMAtomicDecS32(&pPage->cFree);
-    if (cFreeNew < 0)
+    if (ASMAtomicUoReadS32(&pPage->cFree) > 0)
     {
+        int32_t cFreeNew = ASMAtomicDecS32(&pPage->cFree);
+        if (cFreeNew >= 0)
+            return cFreeNew;
         ASMAtomicIncS32(&pPage->cFree);
-        return -1;
     }
-    return cFreeNew;
+    return -1;
 }
 
 
@@ -381,21 +372,21 @@ RTDECL(int) RTMemCacheAllocEx(RTMEMCACHE hMemCache, void **ppvObj)
     PRTMEMCACHEFREEOBJ pObj = ASMAtomicUoReadPtrT(&pThis->pFreeTop, PRTMEMCACHEFREEOBJ);
     if (pObj)
     {
-        do
+        pObj = ASMAtomicXchgPtrT(&pThis->pFreeTop, NULL, PRTMEMCACHEFREEOBJ);
+        if (pObj)
         {
-            PRTMEMCACHEFREEOBJ pNext = ASMAtomicUoReadPtrT(&pObj->pNext, PRTMEMCACHEFREEOBJ);
-            PRTMEMCACHEFREEOBJ pObjOld;
-            if (ASMAtomicCmpXchgExPtr(&pThis->pFreeTop, pNext, pObj, &pObjOld))
+            if (pObj->pNext)
             {
-                Assert(pObjOld == pObj);
-                Assert(pNext != pObjOld);
-                pObj->pNext = NULL;
-                *ppvObj = pObj;
-                return VINF_SUCCESS;
+                Assert(pObj->pNext != pObj);
+                PRTMEMCACHEFREEOBJ pAllocRace = ASMAtomicXchgPtrT(&pThis->pFreeTop, pObj->pNext, PRTMEMCACHEFREEOBJ);
+                if (pAllocRace)
+                    rtMemCacheFreeList(pThis, pAllocRace);
             }
-            pObj = pObjOld;
-            ASMNopPause();
-        } while (pObj);
+
+            pObj->pNext = NULL;
+            *ppvObj = pObj;
+            return VINF_SUCCESS;
+        }
     }
 
     /*
@@ -423,7 +414,7 @@ RTDECL(int) RTMemCacheAllocEx(RTMEMCACHE hMemCache, void **ppvObj)
     /*
      * Grab a free object at the page level.
      */
-    PRTMEMCACHEPAGE pPage = ASMAtomicReadPtrT(&pThis->pPageHint, PRTMEMCACHEPAGE);
+    PRTMEMCACHEPAGE pPage = ASMAtomicUoReadPtrT(&pThis->pPageHint, PRTMEMCACHEPAGE);
     int32_t iObj = pPage ? rtMemCacheGrabObj(pPage) : -1;
     if (iObj < 0)
     {
@@ -501,6 +492,58 @@ RTDECL(void *) RTMemCacheAlloc(RTMEMCACHE hMemCache)
 }
 
 
+
+/**
+ * Really frees one object.
+ *
+ * @param   pThis               The memory cache.
+ * @param   pvObj               The memory object to free.
+ */
+static void rtMemCacheFreeOne(RTMEMCACHEINT *pThis, void *pvObj)
+{
+    /* Note: Do *NOT* attempt to poison the object! */
+
+    /*
+     * Find the cache page.  The page structure is at the start of the page.
+     */
+    PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)(((uintptr_t)pvObj) & ~(uintptr_t)PAGE_OFFSET_MASK);
+    Assert(pPage->pCache == pThis);
+    Assert(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage);
+
+    /*
+     * Clear the bitmap bit and update the two object counter. Order matters!
+     */
+    uintptr_t offObj = (uintptr_t)pvObj - (uintptr_t)pPage->pbObjects;
+    uintptr_t iObj   = offObj / pThis->cbObject;
+    Assert(iObj * pThis->cbObject == offObj);
+    Assert(iObj < pThis->cPerPage);
+    AssertReturnVoid(ASMAtomicBitTestAndClear(pPage->pbmAlloc, iObj));
+
+    ASMAtomicIncS32(&pPage->cFree);
+    ASMAtomicIncS32(&pThis->cFree);
+}
+
+
+/**
+ * Really frees a list of 'freed' object.
+ *
+ * @param   pThis               The memory cache.
+ * @param   pHead               The head of the list.
+ */
+static void rtMemCacheFreeList(RTMEMCACHEINT *pThis, PRTMEMCACHEFREEOBJ pHead)
+{
+    while (pHead)
+    {
+        PRTMEMCACHEFREEOBJ pFreeMe = pHead;
+        pHead = pHead->pNext;
+        pFreeMe->pNext = NULL;
+        ASMCompilerBarrier();
+        rtMemCacheFreeOne(pThis, pFreeMe);
+    }
+}
+
+
+
 RTDECL(void) RTMemCacheFree(RTMEMCACHE hMemCache, void *pvObj)
 {
     if (!pvObj)
@@ -513,7 +556,9 @@ RTDECL(void) RTMemCacheFree(RTMEMCACHE hMemCache, void *pvObj)
     AssertPtr(pvObj);
     Assert(RT_ALIGN_P(pvObj, pThis->cbAlignment) == pvObj);
 
-    if (pThis->fUseFreeList)
+    if (!pThis->fUseFreeList)
+        rtMemCacheFreeOne(pThis, pvObj);
+    else
     {
 # ifdef RT_STRICT
         /* This is the same as the other branch, except it's not actually freed. */
@@ -531,39 +576,10 @@ RTDECL(void) RTMemCacheFree(RTMEMCACHE hMemCache, void *pvObj)
          * Push it onto the free stack.
          */
         PRTMEMCACHEFREEOBJ pObj = (PRTMEMCACHEFREEOBJ)pvObj;
-        PRTMEMCACHEFREEOBJ pNext = ASMAtomicUoReadPtrT(&pThis->pFreeTop, PRTMEMCACHEFREEOBJ);
-        PRTMEMCACHEFREEOBJ pFreeTopOld;
-        pObj->pNext = pNext;
-        while (!ASMAtomicCmpXchgExPtr(&pThis->pFreeTop, pObj, pNext, &pFreeTopOld))
-        {
-            pNext = pFreeTopOld;
-            Assert(pNext != pObj);
-            pObj->pNext = pNext;
-            ASMNopPause();
-        }
-    }
-    else
-    {
-        /* Note: Do *NOT* attempt to poison the object! */
-
-        /*
-         * Find the cache page.  The page structure is at the start of the page.
-         */
-        PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)(((uintptr_t)pvObj) & ~(uintptr_t)PAGE_OFFSET_MASK);
-        Assert(pPage->pCache == pThis);
-        Assert(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage);
-
-        /*
-         * Clear the bitmap bit and update the two object counter. Order matters!
-         */
-        uintptr_t offObj = (uintptr_t)pvObj - (uintptr_t)pPage->pbObjects;
-        uintptr_t iObj   = offObj / pThis->cbObject;
-        Assert(iObj * pThis->cbObject == offObj);
-        Assert(iObj < pThis->cPerPage);
-        AssertReturnVoid(ASMAtomicBitTestAndClear(pPage->pbmAlloc, iObj));
-
-        ASMAtomicIncS32(&pPage->cFree);
-        ASMAtomicIncS32(&pThis->cFree);
+        pObj->pNext = ASMAtomicXchgPtrT(&pThis->pFreeTop, NULL, PRTMEMCACHEFREEOBJ);
+        PRTMEMCACHEFREEOBJ pFreeRace = ASMAtomicXchgPtrT(&pThis->pFreeTop, pObj, PRTMEMCACHEFREEOBJ);
+        if (pFreeRace)
+            rtMemCacheFreeList(pThis, pFreeRace);
     }
 }
 
diff --git a/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac b/src/VBox/Runtime/common/asm/ASMGetXcr0.asm
similarity index 53%
copy from src/VBox/ValidationKit/bootsectors/bootsector2-first.mac
copy to src/VBox/Runtime/common/asm/ASMGetXcr0.asm
index 372f5cc..7a7981e 100644
--- a/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac
+++ b/src/VBox/Runtime/common/asm/ASMGetXcr0.asm
@@ -1,10 +1,10 @@
-; $Id: bootsector2-first.mac $
+; $Id: ASMGetXcr0.asm $
 ;; @file
-; bootsector2 first include file - works around YASM / kBuild issues.
+; IPRT - ASMGetXcr0().
 ;
 
 ;
-; Copyright (C) 2007-2014 Oracle Corporation
+; Copyright (C) 2006-2015 Oracle Corporation
 ;
 ; This file is part of VirtualBox Open Source Edition (OSE), as
 ; available from http://www.virtualbox.org. This file is free software;
@@ -24,51 +24,24 @@
 ; terms and conditions of either the GPL or the CDDL or both.
 ;
 
-%ifndef ___bootsector2_first_mac
-%define ___bootsector2_first_mac
-
-;
-; Undefine thing that shouldn't be defined if we're targetting the
-; binary format directly. These macros comes from DEFS in Config.kmk.
-;
-%ifdef ASM_FORMAT_BIN
- %undef RT_ARCH_AMD64
- %undef RT_ARCH_X86
-
- %undef RT_OS_DARWIN
- %undef RT_OS_FREEBSD
- %undef RT_OS_HAIKU
- %undef RT_OS_LINUX
- %undef RT_OS_NETBSD
- %undef RT_OS_OPENBSD
- %undef RT_OS_OS2
- %undef RT_OS_WINDOWS
-
- %undef __AMD64__
- %undef __x86_64__
- %undef __i386__
- %undef __I386__
- %undef __x86__
- %undef __X86__
-
- %undef __WIN__
- %undef __WIN32__
- %undef __WIN64__
-%endif
-
-
-;
-; Include standard includes.
-;
+;*******************************************************************************
+;* Header Files                                                                *
+;*******************************************************************************
 %include "iprt/asmdefs.mac"
-%include "iprt/x86.mac"
-%include "VBox/VMMDevTesting.mac"
-
 
-;
-; Open the code segment.
-;
 BEGINCODE
 
+;;
+; Gets the content of the XCR0 CPU register.
+; @returns XCR0 value in rax (amd64) / edx:eax (x86).
+;
+BEGINPROC_EXPORTED ASMGetXcr0
+        xor     ecx, ecx                ; XCR0
+        xgetbv
+%ifdef RT_ARCH_AMD64
+        shl     rdx, 32
+        or      rax, rdx
 %endif
+        ret
+ENDPROC ASMGetXcr0
 
diff --git a/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac b/src/VBox/Runtime/common/asm/ASMSetXcr0.asm
similarity index 52%
copy from src/VBox/ValidationKit/bootsectors/bootsector2-first.mac
copy to src/VBox/Runtime/common/asm/ASMSetXcr0.asm
index 372f5cc..d7725a8 100644
--- a/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac
+++ b/src/VBox/Runtime/common/asm/ASMSetXcr0.asm
@@ -1,10 +1,10 @@
-; $Id: bootsector2-first.mac $
+; $Id: ASMSetXcr0.asm $
 ;; @file
-; bootsector2 first include file - works around YASM / kBuild issues.
+; IPRT - ASMSetXcr0().
 ;
 
 ;
-; Copyright (C) 2007-2014 Oracle Corporation
+; Copyright (C) 2006-2015 Oracle Corporation
 ;
 ; This file is part of VirtualBox Open Source Edition (OSE), as
 ; available from http://www.virtualbox.org. This file is free software;
@@ -24,51 +24,35 @@
 ; terms and conditions of either the GPL or the CDDL or both.
 ;
 
-%ifndef ___bootsector2_first_mac
-%define ___bootsector2_first_mac
-
-;
-; Undefine thing that shouldn't be defined if we're targetting the
-; binary format directly. These macros comes from DEFS in Config.kmk.
-;
-%ifdef ASM_FORMAT_BIN
- %undef RT_ARCH_AMD64
- %undef RT_ARCH_X86
-
- %undef RT_OS_DARWIN
- %undef RT_OS_FREEBSD
- %undef RT_OS_HAIKU
- %undef RT_OS_LINUX
- %undef RT_OS_NETBSD
- %undef RT_OS_OPENBSD
- %undef RT_OS_OS2
- %undef RT_OS_WINDOWS
-
- %undef __AMD64__
- %undef __x86_64__
- %undef __i386__
- %undef __I386__
- %undef __x86__
- %undef __X86__
-
- %undef __WIN__
- %undef __WIN32__
- %undef __WIN64__
-%endif
-
-
-;
-; Include standard includes.
-;
+;*******************************************************************************
+;* Header Files                                                                *
+;*******************************************************************************
 %include "iprt/asmdefs.mac"
-%include "iprt/x86.mac"
-%include "VBox/VMMDevTesting.mac"
 
-
-;
-; Open the code segment.
-;
 BEGINCODE
 
+;;
+; Sets the content of the Xcr0 CPU register.
+; @param   uXcr0    The new XCR0 content.
+;                   msc=rcx, gcc=rdi, x86=[esp+4]
+;
+BEGINPROC_EXPORTED ASMSetXcr0
+%ifdef ASM_CALL64_MSC
+        mov     rdx, rcx
+        shr     rdx, 32
+        mov     eax, ecx
+%elifdef ASM_CALL64_GCC
+        mov     rdx, rdi
+        shr     rdx, 32
+        mov     eax, edi
+%elifdef RT_ARCH_X86
+        mov     eax, [esp + 4]
+        mov     edx, [esp + 8]
+%else
+ %error "Undefined arch?"
 %endif
+        xor     ecx, ecx
+        xsetbv
+        ret
+ENDPROC ASMSetXcr0
 
diff --git a/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c b/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
index 2486fd1..3fc3b9e 100644
--- a/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
+++ b/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
@@ -168,14 +168,18 @@ DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
             VM_OBJECT_LOCK(pMemFreeBSD->pObject);
 #endif
             vm_page_t pPage = vm_page_find_least(pMemFreeBSD->pObject, 0);
+#if __FreeBSD_version < 1000000
             vm_page_lock_queues();
+#endif
             for (vm_page_t pPage = vm_page_find_least(pMemFreeBSD->pObject, 0);
                  pPage != NULL;
                  pPage = vm_page_next(pPage))
             {
                 vm_page_unwire(pPage, 0);
             }
+#if __FreeBSD_version < 1000000
             vm_page_unlock_queues();
+#endif
 #if __FreeBSD_version >= 1000030
             VM_OBJECT_WUNLOCK(pMemFreeBSD->pObject);
 #else
@@ -291,11 +295,15 @@ static int rtR0MemObjFreeBSDPhysAllocHelper(vm_object_t pObject, u_long cPages,
             while (iPage-- > 0)
             {
                 pPage = vm_page_lookup(pObject, iPage);
+#if __FreeBSD_version < 1000000
                 vm_page_lock_queues();
+#endif
                 if (fWire)
                     vm_page_unwire(pPage, 0);
                 vm_page_free(pPage);
+#if __FreeBSD_version < 1000000
                 vm_page_unlock_queues();
+#endif
             }
 #if __FreeBSD_version >= 1000030
             VM_OBJECT_WUNLOCK(pObject);
diff --git a/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
index 9202ec3..896b8b0 100644
--- a/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/initterm-r0drv-linux.c
@@ -95,7 +95,11 @@ DECLHIDDEN(void) rtR0LnxWorkqueueFlush(void)
 DECLHIDDEN(int) rtR0InitNative(void)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
     g_prtR0LnxWorkQueue = create_workqueue("iprt-VBoxWQueue");
+ #else
+    g_prtR0LnxWorkQueue = create_workqueue("iprt-VBoxQ");
+ #endif
     if (!g_prtR0LnxWorkQueue)
         return VERR_NO_MEMORY;
 #endif
diff --git a/src/VBox/Runtime/r3/freebsd/systemmem-freebsd.cpp b/src/VBox/Runtime/r3/freebsd/systemmem-freebsd.cpp
new file mode 100644
index 0000000..a7533a6
--- /dev/null
+++ b/src/VBox/Runtime/r3/freebsd/systemmem-freebsd.cpp
@@ -0,0 +1,98 @@
+/* $Id: systemmem-freebsd.cpp $ */
+/** @file
+ * IPRT - RTSystemQueryTotalRam, Linux ring-3.
+ */
+
+/*
+ * Copyright (C) 2012-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <iprt/system.h>
+#include "internal/iprt.h"
+
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <errno.h>
+
+
+RTDECL(int) RTSystemQueryTotalRam(uint64_t *pcb)
+{
+    int rc = VINF_SUCCESS;
+    u_long cbMemPhys = 0;
+    size_t cbParameter = sizeof(cbMemPhys);
+
+    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+
+    if (!sysctlbyname("hw.physmem", &cbMemPhys, &cbParameter, NULL, 0))
+    {
+        *pcb = cbMemPhys;
+        return VINF_SUCCESS;
+    }
+    return RTErrConvertFromErrno(errno);
+}
+
+
+RTDECL(int) RTSystemQueryAvailableRam(uint64_t *pcb)
+{
+    AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+
+    int rc = VINF_SUCCESS;
+    u_int cPagesMemFree = 0;
+    u_int cPagesMemInactive = 0;
+    u_int cPagesMemCached = 0;
+    u_int cPagesMemUsed = 0;
+    int cbPage = 0;
+    size_t cbParameter;
+    int cProcessed = 0;
+
+    cbParameter = sizeof(cPagesMemFree);
+    if (sysctlbyname("vm.stats.vm.v_free_count", &cPagesMemFree, &cbParameter, NULL, 0))
+        rc = RTErrConvertFromErrno(errno);
+    cbParameter = sizeof(cPagesMemUsed);
+    if (   RT_SUCCESS(rc)
+        && sysctlbyname("vm.stats.vm.v_active_count", &cPagesMemUsed, &cbParameter, NULL, 0))
+        rc = RTErrConvertFromErrno(errno);
+    cbParameter = sizeof(cPagesMemInactive);
+    if (   RT_SUCCESS(rc)
+        && sysctlbyname("vm.stats.vm.v_inactive_count", &cPagesMemInactive, &cbParameter, NULL, 0))
+        rc = RTErrConvertFromErrno(errno);
+    cbParameter = sizeof(cPagesMemCached);
+    if (   RT_SUCCESS(rc)
+        && sysctlbyname("vm.stats.vm.v_cache_count", &cPagesMemCached, &cbParameter, NULL, 0))
+        rc = RTErrConvertFromErrno(errno);
+    cbParameter = sizeof(cbPage);
+    if (   RT_SUCCESS(rc)
+        && sysctlbyname("hw.pagesize", &cbPage, &cbParameter, NULL, 0))
+        rc = RTErrConvertFromErrno(errno);
+
+    if (RT_SUCCESS(rc))
+        *pcb = (cPagesMemFree + cPagesMemInactive + cPagesMemCached ) * cbPage;
+
+    return rc;
+}
+
diff --git a/src/VBox/Runtime/r3/win/process-win.cpp b/src/VBox/Runtime/r3/win/process-win.cpp
index fd0dfba..f4c14ee 100644
--- a/src/VBox/Runtime/r3/win/process-win.cpp
+++ b/src/VBox/Runtime/r3/win/process-win.cpp
@@ -845,13 +845,13 @@ static int rtProcWinCreateAsUser2(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTU
                 dwErr = NO_ERROR;
 
                 PSID pSid = (PSID)RTMemAlloc(cbSid * sizeof(wchar_t)); /** @todo r=bird: What's the relationship between wchar_t and PSID? */
-                AssertPtrReturn(pSid, VERR_NO_MEMORY); /** @todo r=bird: Leaking token handles when we're out of memory...  */
+                AssertReturn(pSid, VERR_NO_MEMORY); /** @todo r=bird: Leaking token handles when we're out of memory...  */
 
                 PRTUTF16 pwszDomain = NULL;
                 if (cchDomain > 0)
                 {
                     pwszDomain = (PRTUTF16)RTMemAlloc(cchDomain * sizeof(RTUTF16));
-                    AssertPtrReturn(pwszDomain, VERR_NO_MEMORY); /** @todo r=bird: Leaking token handles when we're out of memory...  */
+                    AssertReturn(pwszDomain, VERR_NO_MEMORY); /** @todo r=bird: Leaking token handles when we're out of memory...  */
                 }
 
                 /* Note: Also supports FQDNs! */
diff --git a/src/VBox/Storage/testcase/BuiltinTests.h b/src/VBox/Storage/testcase/BuiltinTests.h
index 072ff41..83a65af 100644
--- a/src/VBox/Storage/testcase/BuiltinTests.h
+++ b/src/VBox/Storage/testcase/BuiltinTests.h
@@ -22,6 +22,8 @@
  */
 typedef struct TSTVDIOTESTENTRY
 {
+    /** Test name. */
+    const char             *pszName;
     /** Pointer to the raw bytes. */
     const unsigned char    *pch;
     /** Number of bytes. */
@@ -31,7 +33,7 @@ typedef struct TSTVDIOTESTENTRY
 typedef TSTVDIOTESTENTRY const *PCTSTVDIOTESTENTRY;
 
 /** Macro for simplifying generating the trust anchor tables. */
-#define TSTVDIOTESTENTRY_GEN(a_abTest)      { &a_abTest[0], sizeof(a_abTest) }
+#define TSTVDIOTESTENTRY_GEN(a_szName, a_abTest)      { #a_szName, &a_abTest[0], sizeof(a_abTest) }
 
 /** All tests we know. */
 extern TSTVDIOTESTENTRY const       g_aVDIoTests[];
diff --git a/src/VBox/Storage/testcase/Makefile.kmk b/src/VBox/Storage/testcase/Makefile.kmk
index 01c21b7..6aeeca8 100644
--- a/src/VBox/Storage/testcase/Makefile.kmk
+++ b/src/VBox/Storage/testcase/Makefile.kmk
@@ -65,7 +65,7 @@ ifdef VBOX_WITH_TESTCASES
 
  # 1=name, 2=filter
  TSTVDIO_GEN_TEST_MACRO = 'TSTVDIOTESTENTRY const g_a$(1)[] =' '{' \
-	$(foreach testnm,$(filter $(2),$(TSTVDIO_BUILTIN_TEST_NAMES)), '    TSTVDIOTESTENTRY_GEN(g_ab$(testnm)),') \
+	$(foreach testnm,$(filter $(2),$(TSTVDIO_BUILTIN_TEST_NAMES)), '    TSTVDIOTESTENTRY_GEN($(testnm), g_ab$(testnm)),') \
 	'};' 'unsigned const g_c$(1) = RT_ELEMENTS(g_a$(1));' '' ''
 
  $$(TSTVDIO_BUILTIN_TESTS_FILE): $(MAKEFILE_CURRENT) \
diff --git a/src/VBox/Storage/testcase/tstVDIo.cpp b/src/VBox/Storage/testcase/tstVDIo.cpp
index 858272a..a992798 100644
--- a/src/VBox/Storage/testcase/tstVDIo.cpp
+++ b/src/VBox/Storage/testcase/tstVDIo.cpp
@@ -971,6 +971,7 @@ static DECLCALLBACK(int) vdScriptHandlerIo(PVDSCRIPTARG paScriptArgs, void *pvUs
 
             tstVDIoTestDestroy(&IoTest);
         }
+        RTTestSubDone(pGlob->hTest);
     }
 
     return rc;
@@ -2693,9 +2694,10 @@ static int tstVDIoPatternGetBuffer(PVDPATTERN pPattern, void **ppv, size_t cb)
  * Executes the given script.
  *
  * @returns nothing.
+ * @param   pszName      The script name.
  * @param   pszScript    The script to execute.
  */
-static void tstVDIoScriptExec(const char *pszScript)
+static void tstVDIoScriptExec(const char *pszName, const char *pszScript)
 {
     int rc = VINF_SUCCESS;
     VDTESTGLOB GlobTest;   /**< Global test data. */
@@ -2738,7 +2740,7 @@ static void tstVDIoScriptExec(const char *pszScript)
                         &GlobTest, sizeof(VDINTERFACEIO), &GlobTest.pInterfacesImages);
     AssertRC(rc);
 
-    rc = RTTestCreate("tstVDIo", &GlobTest.hTest);
+    rc = RTTestCreate(pszName, &GlobTest.hTest);
     if (RT_SUCCESS(rc))
     {
         /* Init I/O backend. */
@@ -2795,7 +2797,7 @@ static void tstVDIoScriptRun(const char *pcszFilename)
         RTFileReadAllFree(pvFile, cbFile);
 
         AssertPtr(pszScript);
-        tstVDIoScriptExec(pszScript);
+        tstVDIoScriptExec(pcszFilename, pszScript);
         RTStrFree(pszScript);
     }
     else
@@ -2834,7 +2836,7 @@ static void tstVDIoRunBuiltinTests(void)
         char *pszScript = RTStrDupN((const char *)g_aVDIoTests[i].pch, g_aVDIoTests[i].cb);
 
         AssertPtr(pszScript);
-        tstVDIoScriptExec(pszScript);
+        tstVDIoScriptExec(g_aVDIoTests[i].pszName, pszScript);
     }
 #endif
 }
diff --git a/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp b/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
index bef5b45..8a9c219 100644
--- a/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
+++ b/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
@@ -49,6 +49,9 @@
 # pragma optimize("y", off)
 #endif
 
+AssertCompile2MemberOffsets(VM, cpum.s.HostFeatures,  cpum.ro.HostFeatures);
+AssertCompile2MemberOffsets(VM, cpum.s.GuestFeatures, cpum.ro.GuestFeatures);
+
 
 /*******************************************************************************
 *   Defined Constants And Macros                                               *
@@ -741,9 +744,23 @@ VMMDECL(int) CPUMSetGuestCR3(PVMCPU pVCpu, uint64_t cr3)
 
 VMMDECL(int) CPUMSetGuestCR4(PVMCPU pVCpu, uint64_t cr4)
 {
-    if (    (cr4                     & (X86_CR4_PGE | X86_CR4_PAE | X86_CR4_PSE))
-        !=  (pVCpu->cpum.s.Guest.cr4 & (X86_CR4_PGE | X86_CR4_PAE | X86_CR4_PSE)))
+    /*
+     * The CR4.OSXSAVE bit is reflected in CPUID(1).ECX[27].
+     */
+    if (   (cr4                     & X86_CR4_OSXSAVE)
+        != (pVCpu->cpum.s.Guest.cr4 & X86_CR4_OSXSAVE) )
+    {
+        PVM pVM = pVCpu->CTX_SUFF(pVM);
+        if (cr4 & X86_CR4_OSXSAVE)
+            CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_OSXSAVE);
+        else
+            CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_OSXSAVE);
+    }
+
+    if (   (cr4                     & (X86_CR4_PGE | X86_CR4_PAE | X86_CR4_PSE))
+        != (pVCpu->cpum.s.Guest.cr4 & (X86_CR4_PGE | X86_CR4_PAE | X86_CR4_PSE)))
         pVCpu->cpum.s.fChanged |= CPUM_CHANGED_GLOBAL_TLB_FLUSH;
+
     pVCpu->cpum.s.fChanged |= CPUM_CHANGED_CR4;
     pVCpu->cpum.s.Guest.cr4 = cr4;
     return VINF_SUCCESS;
@@ -1283,14 +1300,18 @@ VMMDECL(void) CPUMGetGuestCpuId(PVMCPU pVCpu, uint32_t uLeaf, uint32_t uSubLeaf,
             /*
              * Deal with CPU specific information (currently only APIC ID).
              */
-            if (pLeaf->fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC_ID)
+            if (pLeaf->fFlags & (CPUMCPUIDLEAF_F_CONTAINS_APIC_ID | CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE))
             {
                 if (uLeaf == 1)
                 {
-                    /* Bits 31-24: Initial APIC ID */
+                    /* EBX: Bits 31-24: Initial APIC ID. */
                     Assert(pVCpu->idCpu <= 255);
                     AssertMsg((pLeaf->uEbx >> 24) == 0, ("%#x\n", pLeaf->uEbx)); /* raw-mode assumption */
                     *pEbx = (pLeaf->uEbx & UINT32_C(0x00ffffff)) | (pVCpu->idCpu << 24);
+
+                    /* ECX: Bit 27: CR4.OSXSAVE mirror. */
+                    *pEcx = (pLeaf->uEcx & ~X86_CPUID_FEATURE_ECX_OSXSAVE)
+                          | (pVCpu->cpum.s.Guest.cr4 & X86_CR4_OSXSAVE ? X86_CPUID_FEATURE_ECX_OSXSAVE : 0);
                 }
                 else if (uLeaf == 0xb)
                 {
@@ -1588,6 +1609,23 @@ VMMDECL(void) CPUMSetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature)
             LogRel(("CPUM: SetGuestCpuIdFeature: Enabled MWAIT Extensions.\n"));
             break;
 
+        /*
+         * OSXSAVE - only used from CPUMSetGuestCR4.
+         */
+        case CPUMCPUIDFEATURE_OSXSAVE:
+            AssertLogRelReturnVoid(pVM->cpum.s.HostFeatures.fXSaveRstor && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor);
+
+            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
+            AssertLogRelReturnVoid(pLeaf);
+
+            /* UNI: Special case for single CPU to make life simple for CPUMPatchHlpCpuId. */
+            if (pVM->cCpus == 1)
+                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx |= X86_CPUID_FEATURE_ECX_OSXSAVE;
+            /* SMP: Set flag indicating OSXSAVE updating (superfluous because of the APIC ID, but that's fine). */
+            else
+                ASMAtomicOrU32(&pLeaf->fFlags, CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE);
+            break;
+
         default:
             AssertMsgFailed(("enmFeature=%d\n", enmFeature));
             break;
@@ -1625,6 +1663,7 @@ VMMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature)
         case CPUMCPUIDFEATURE_HVP:          return pVM->cpum.s.GuestFeatures.fHypervisorPresent;
         case CPUMCPUIDFEATURE_MWAIT_EXTS:   return pVM->cpum.s.GuestFeatures.fMWaitExtensions;
 
+        case CPUMCPUIDFEATURE_OSXSAVE:
         case CPUMCPUIDFEATURE_INVALID:
         case CPUMCPUIDFEATURE_32BIT_HACK:
             break;
@@ -1732,6 +1771,22 @@ VMMDECL(void) CPUMClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature)
             Log(("CPUM: ClearGuestCpuIdFeature: Disabled MWAIT Extensions!\n"));
             break;
 
+        /*
+         * OSXSAVE - only used from CPUMSetGuestCR4.
+         */
+        case CPUMCPUIDFEATURE_OSXSAVE:
+            AssertLogRelReturnVoid(pVM->cpum.s.HostFeatures.fXSaveRstor && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor);
+
+            pLeaf = cpumCpuIdGetLeaf(pVM, UINT32_C(0x00000001));
+            AssertLogRelReturnVoid(pLeaf);
+
+            /* UNI: Special case for single CPU to make life easy for CPUMPatchHlpCpuId. */
+            if (pVM->cCpus == 1)
+                pVM->cpum.s.aGuestCpuIdPatmStd[1].uEcx = pLeaf->uEcx &= ~X86_CPUID_FEATURE_ECX_OSXSAVE;
+            /* else: SMP: We never set the OSXSAVE bit and leaving the CONTAINS_OSXSAVE flag is fine. */
+            break;
+
+
         default:
             AssertMsgFailed(("enmFeature=%d\n", enmFeature));
             break;
diff --git a/src/VBox/VMM/VMMAll/EMAll.cpp b/src/VBox/VMM/VMMAll/EMAll.cpp
index a04ec0a..860b260 100644
--- a/src/VBox/VMM/VMMAll/EMAll.cpp
+++ b/src/VBox/VMM/VMMAll/EMAll.cpp
@@ -1452,7 +1452,7 @@ static int emUpdateCRx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t D
     NOREF(pVM);
 
     /** @todo Clean up this mess. */
-    LogFlow(("EMInterpretCRxWrite at %RGv CR%d <- %RX64\n", (RTGCPTR)pRegFrame->rip, DestRegCrx, val));
+    LogFlow(("emInterpretCRxWrite at %RGv CR%d <- %RX64\n", (RTGCPTR)pRegFrame->rip, DestRegCrx, val));
     Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
     switch (DestRegCrx)
     {
@@ -1609,7 +1609,7 @@ static int emUpdateCRx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t D
  * @param   SrcRegGen   General purpose register index (USE_REG_E**))
  *
  */
-VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen)
+static int emInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen)
 {
     uint64_t val;
     int      rc;
@@ -1630,47 +1630,6 @@ VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFr
     return VERR_EM_INTERPRETER;
 }
 
-/**
- * Interpret LMSW.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pRegFrame   The register frame.
- * @param   u16Data     LMSW source data.
- *
- */
-VMM_INT_DECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data)
-{
-    Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
-    uint64_t OldCr0 = CPUMGetGuestCR0(pVCpu);
-
-    /* Only PE, MP, EM and TS can be changed; note that PE can't be cleared by this instruction. */
-    uint64_t NewCr0 = ( OldCr0 & ~(             X86_CR0_MP | X86_CR0_EM | X86_CR0_TS))
-                    | (u16Data &  (X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS));
-
-    return emUpdateCRx(pVM, pVCpu, pRegFrame, DISCREG_CR0, NewCr0);
-}
-
-
-/**
- * Interpret CLTS.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- *
- */
-VMM_INT_DECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu)
-{
-    NOREF(pVM);
-
-    uint64_t cr0 = CPUMGetGuestCR0(pVCpu);
-    if (!(cr0 & X86_CR0_TS))
-        return VINF_SUCCESS;
-    return CPUMSetGuestCR0(pVCpu, cr0 & ~X86_CR0_TS);
-}
-
 
 #ifdef LOG_ENABLED
 static const char *emMSRtoString(uint32_t uMsr)
@@ -1804,7 +1763,7 @@ VMM_INT_DECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame
  * @param   SrcRegCRx   CRx register index (DISUSE_REG_CR*)
  *
  */
-VMM_INT_DECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx)
+static int emInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx)
 {
     Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
     uint64_t val64;
@@ -3350,8 +3309,12 @@ static int emInterpretCpuId(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCO
  */
 static int emInterpretClts(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
 {
-    NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize);
-    return EMInterpretCLTS(pVM, pVCpu);
+    NOREF(pVM); NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize);
+
+    uint64_t cr0 = CPUMGetGuestCR0(pVCpu);
+    if (!(cr0 & X86_CR0_TS))
+        return VINF_SUCCESS;
+    return CPUMSetGuestCR0(pVCpu, cr0 & ~X86_CR0_TS);
 }
 
 
@@ -3363,6 +3326,7 @@ static int emInterpretLmsw(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCOR
     DISQPVPARAMVAL param1;
     uint32_t    val;
     NOREF(pvFault); NOREF(pcbSize);
+    Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
 
     int rc = DISQueryParamVal(pRegFrame, pDis, &pDis->Param1, &param1, DISQPVWHICH_SRC);
     if(RT_FAILURE(rc))
@@ -3382,7 +3346,14 @@ static int emInterpretLmsw(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCOR
     }
 
     LogFlow(("emInterpretLmsw %x\n", val));
-    return EMInterpretLMSW(pVM, pVCpu, pRegFrame, val);
+    uint64_t OldCr0 = CPUMGetGuestCR0(pVCpu);
+
+    /* Only PE, MP, EM and TS can be changed; note that PE can't be cleared by this instruction. */
+    uint64_t NewCr0 = ( OldCr0 & ~(             X86_CR0_MP | X86_CR0_EM | X86_CR0_TS))
+                    | (val     &  (X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS));
+
+    return emUpdateCRx(pVM, pVCpu, pRegFrame, DISCREG_CR0, NewCr0);
+
 }
 
 #ifdef EM_EMULATE_SMSW
@@ -3445,10 +3416,10 @@ static int emInterpretMovCRx(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXC
 {
     NOREF(pvFault); NOREF(pcbSize);
     if ((pDis->Param1.fUse == DISUSE_REG_GEN32 || pDis->Param1.fUse == DISUSE_REG_GEN64) && pDis->Param2.fUse == DISUSE_REG_CR)
-        return EMInterpretCRxRead(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxGenReg, pDis->Param2.Base.idxCtrlReg);
+        return emInterpretCRxRead(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxGenReg, pDis->Param2.Base.idxCtrlReg);
 
     if (pDis->Param1.fUse == DISUSE_REG_CR && (pDis->Param2.fUse == DISUSE_REG_GEN32 || pDis->Param2.fUse == DISUSE_REG_GEN64))
-        return EMInterpretCRxWrite(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxCtrlReg, pDis->Param2.Base.idxGenReg);
+        return emInterpretCRxWrite(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxCtrlReg, pDis->Param2.Base.idxGenReg);
 
     AssertMsgFailedReturn(("Unexpected control register move\n"), VERR_EM_INTERPRETER);
 }
diff --git a/src/VBox/VMM/VMMAll/GIMAll.cpp b/src/VBox/VMM/VMMAll/GIMAll.cpp
index d788614..b96fd97 100644
--- a/src/VBox/VMM/VMMAll/GIMAll.cpp
+++ b/src/VBox/VMM/VMMAll/GIMAll.cpp
@@ -128,6 +128,9 @@ VMM_INT_DECL(bool) GIMIsParavirtTscEnabled(PVM pVM)
         case GIMPROVIDERID_HYPERV:
             return gimHvIsParavirtTscEnabled(pVM);
 
+        case GIMPROVIDERID_KVM:
+            return gimKvmIsParavirtTscEnabled(pVM);
+
         default:
             break;
     }
@@ -145,20 +148,21 @@ VMM_INT_DECL(bool) GIMIsParavirtTscEnabled(PVM pVM)
  * really required.
  *
  * @returns true if needed, false otherwise.
- * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
  */
-VMM_INT_DECL(bool) GIMShouldTrapXcptUD(PVM pVM)
+VMM_INT_DECL(bool) GIMShouldTrapXcptUD(PVMCPU pVCpu)
 {
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
     if (!GIMIsEnabled(pVM))
-        return 0;
+        return false;
 
     switch (pVM->gim.s.enmProviderId)
     {
         case GIMPROVIDERID_KVM:
-            return gimKvmShouldTrapXcptUD(pVM);
+            return gimKvmShouldTrapXcptUD(pVCpu);
 
         default:
-            return 0;
+            return false;
     }
 }
 
@@ -168,8 +172,10 @@ VMM_INT_DECL(bool) GIMShouldTrapXcptUD(PVM pVM)
  *
  * @param   pVCpu       Pointer to the VMCPU.
  * @param   pCtx        Pointer to the guest-CPU context.
+ * @param   pDis        Pointer to the disassembled instruction state at RIP.
+ *                      Optional, can be NULL.
  */
-VMM_INT_DECL(int) GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx)
+VMM_INT_DECL(int) GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis)
 {
     PVM pVM = pVCpu->CTX_SUFF(pVM);
     Assert(GIMIsEnabled(pVM));
@@ -177,7 +183,7 @@ VMM_INT_DECL(int) GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx)
     switch (pVM->gim.s.enmProviderId)
     {
         case GIMPROVIDERID_KVM:
-            return gimKvmXcptUD(pVCpu, pCtx);
+            return gimKvmXcptUD(pVCpu, pCtx, pDis);
 
         default:
             return VERR_GIM_OPERATION_FAILED;
diff --git a/src/VBox/VMM/VMMAll/GIMAllKvm.cpp b/src/VBox/VMM/VMMAll/GIMAllKvm.cpp
index fbd1e69..18c1e47 100644
--- a/src/VBox/VMM/VMMAll/GIMAllKvm.cpp
+++ b/src/VBox/VMM/VMMAll/GIMAllKvm.cpp
@@ -111,10 +111,7 @@ VMM_INT_DECL(int) gimKvmHypercall(PVMCPU pVCpu, PCPUMCTX pCtx)
     /*
      * Place the result in rax/eax.
      */
-    if (fIs64BitMode)
-        pCtx->rax = uHyperRet;
-    else
-        pCtx->eax = uHyperRet & uAndMask;
+    pCtx->rax = uHyperRet & uAndMask;
     return VINF_SUCCESS;
 }
 
@@ -143,7 +140,15 @@ VMM_INT_DECL(bool) gimKvmAreHypercallsEnabled(PVMCPU pVCpu)
  */
 VMM_INT_DECL(bool) gimKvmIsParavirtTscEnabled(PVM pVM)
 {
-    return false;   /** @todo implement this! */
+    uint32_t cCpus = pVM->cCpus;
+    for (uint32_t i = 0; i < cCpus; i++)
+    {
+        PVMCPU     pVCpu      = &pVM->aCpus[i];
+        PGIMKVMCPU pGimKvmCpu = &pVCpu->gim.s.u.KvmCpu;
+        if (MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(pGimKvmCpu->u64SystemTimeMsr))
+            return true;
+    }
+    return false;
 }
 
 
@@ -222,7 +227,7 @@ VMM_INT_DECL(VBOXSTRICTRC) gimKvmWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMS
 #ifndef IN_RING3
             if (fEnable)
             {
-                RTCCUINTREG fEFlags = ASMIntDisableFlags();
+                RTCCUINTREG fEFlags  = ASMIntDisableFlags();
                 pKvmCpu->uTsc        = TMCpuTickGetNoCheck(pVCpu);
                 pKvmCpu->uVirtNanoTS = TMVirtualGetNoCheck(pVM);
                 ASMSetFlags(fEFlags);
@@ -316,11 +321,13 @@ VMM_INT_DECL(VBOXSTRICTRC) gimKvmWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMS
  * of the two CPU models (Intel or AMD). Hyper-V solves this problem more
  * elegantly by letting the hypervisor supply an opaque hypercall page.
  *
- * @param   pVM         Pointer to the VM.
+ * For raw-mode VMs, this function will always return true. See gimR3KvmInit().
+ *
+ * @param   pVCpu       Pointer to the VMCPU.
  */
-VMM_INT_DECL(bool) gimKvmShouldTrapXcptUD(PVM pVM)
+VMM_INT_DECL(bool) gimKvmShouldTrapXcptUD(PVMCPU pVCpu)
 {
-    pVM->gim.s.u.Kvm.fTrapXcptUD = ASMIsAmdCpu();
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
     return pVM->gim.s.u.Kvm.fTrapXcptUD;
 }
 
@@ -330,36 +337,75 @@ VMM_INT_DECL(bool) gimKvmShouldTrapXcptUD(PVM pVM)
  *
  * @param   pVCpu       Pointer to the VMCPU.
  * @param   pCtx        Pointer to the guest-CPU context.
+ * @param   pDis        Pointer to the disassembled instruction state at RIP.
+ *                      Optional, can be NULL.
  */
-VMM_INT_DECL(int) gimKvmXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx)
+VMM_INT_DECL(int) gimKvmXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis)
 {
     /*
      * If we didn't ask for #UD to be trapped, bail.
      */
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
+    PVM     pVM  = pVCpu->CTX_SUFF(pVM);
+    PGIMKVM pKvm = &pVM->gim.s.u.Kvm;
     if (RT_UNLIKELY(!pVM->gim.s.u.Kvm.fTrapXcptUD))
         return VERR_GIM_OPERATION_FAILED;
 
     /*
-     * Disassemble the instruction at RIP to figure out if it's the Intel
-     * VMCALL instruction and if so, handle it as a hypercall.
+     * Make sure guest ring-0 is the one making the hypercall.
      */
-    DISCPUSTATE Dis;
-    unsigned    cbInstr;
-    int rc = EMInterpretDisasCurrent(pVM, pVCpu, &Dis, &cbInstr);
+    if (CPUMGetGuestCPL(pVCpu))
+        return VERR_GIM_HYPERCALL_ACCESS_DENIED;
+
+    int rc = VINF_SUCCESS;
+    if (!pDis)
+    {
+        /*
+         * Disassemble the instruction at RIP to figure out if it's the Intel
+         * VMCALL instruction and if so, handle it as a hypercall.
+         */
+        DISCPUSTATE Dis;
+        rc = EMInterpretDisasCurrent(pVM, pVCpu, &Dis, NULL /* pcbInstr */);
+        pDis = &Dis;
+    }
+
     if (RT_SUCCESS(rc))
     {
-        if (Dis.pCurInstr->uOpcode == OP_VMCALL)
+        /*
+         * Patch the instruction to so we don't have to spend time disassembling it each time.
+         * Makes sense only for HM as with raw-mode we will be getting a #UD regardless.
+         */
+        if (   pDis->pCurInstr->uOpcode == OP_VMCALL
+            || pDis->pCurInstr->uOpcode == OP_VMMCALL)
         {
+            uint8_t abHypercall[3];
+            if (   pDis->pCurInstr->uOpcode != pKvm->uOpCodeNative
+                && HMIsEnabled(pVM))
+            {
+                size_t  cbWritten = 0;
+                rc = VMMPatchHypercall(pVM, &abHypercall, sizeof(abHypercall), &cbWritten);
+                AssertRC(rc);
+                Assert(sizeof(abHypercall) == pDis->cbInstr);
+                Assert(sizeof(abHypercall) == cbWritten);
+
+                rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, &abHypercall, sizeof(abHypercall));
+            }
+
             /*
-             * Patch the instruction to so we don't have to spend time disassembling it each time.
+             * Perform the hypercall and update RIP.
+             *
+             * For HM, we can simply resume guest execution without perform the hypercall now and
+             * do it on the next VMCALL/VMMCALL exit handler on the patched instruction.
+             *
+             * For raw-mode we need to do this now anyway. So we do it here regardless with an added
+             * advantage is that it saves one world-switch for the HM case.
              */
-            static uint8_t s_abHypercall[3] = { 0x0F, 0x01, 0x00 };
-            Assert(sizeof(s_abHypercall) == cbInstr);
-            if (!s_abHypercall[2])
-                s_abHypercall[2] = ASMIsAmdCpu() ? 0xD9 /* VMMCALL */ : 0xC1 /* VMCALL */;
-            rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, &s_abHypercall, sizeof(s_abHypercall));
-            return VINF_SUCCESS;
+            if (RT_SUCCESS(rc))
+            {
+                int rc2 = gimKvmHypercall(pVCpu, pCtx);
+                AssertRC(rc2);
+                pCtx->rip += pDis->cbInstr;
+            }
+            return rc;
         }
     }
 
diff --git a/src/VBox/VMM/VMMAll/HMAll.cpp b/src/VBox/VMM/VMMAll/HMAll.cpp
index 48a07ee..8410d06 100644
--- a/src/VBox/VMM/VMMAll/HMAll.cpp
+++ b/src/VBox/VMM/VMMAll/HMAll.cpp
@@ -507,45 +507,47 @@ VMM_INT_DECL(bool) HMSetSingleInstruction(PVMCPU pVCpu, bool fEnable)
 
 
 /**
- * Patches the instructions necessary for making a hypercall to the hypervisor.
- * Used by GIM.
+ * Notifies HM that paravirtualized hypercalls are now enabled.
  *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pvBuf       The buffer in the hypercall page(s) to be patched.
- * @param   cbBuf       The size of the buffer.
- * @param   pcbWritten  Where to store the number of bytes patched. This
- *                      is reliably updated only when this function returns
- *                      VINF_SUCCESS.
+ * @param   pVCpu   Pointer to the VMCPU.
  */
-VMM_INT_DECL(int) HMPatchHypercall(PVM pVM, void *pvBuf, size_t cbBuf, size_t *pcbWritten)
+VMM_INT_DECL(void) HMHypercallsEnable(PVMCPU pVCpu)
 {
-    AssertReturn(pvBuf, VERR_INVALID_POINTER);
-    AssertReturn(pcbWritten, VERR_INVALID_POINTER);
-    AssertReturn(HMIsEnabled(pVM), VERR_HM_IPE_5);
+    pVCpu->hm.s.fHypercallsEnabled = true;
+}
 
-    if (pVM->hm.s.vmx.fSupported)
-    {
-        uint8_t abHypercall[] = { 0x0F, 0x01, 0xC1 };   /* VMCALL */
-        if (RT_LIKELY(cbBuf >= sizeof(abHypercall)))
-        {
-            memcpy(pvBuf, abHypercall, sizeof(abHypercall));
-            *pcbWritten = sizeof(abHypercall);
-            return VINF_SUCCESS;
-        }
-        return VERR_BUFFER_OVERFLOW;
-    }
-    else
-    {
-        Assert(pVM->hm.s.svm.fSupported);
-        uint8_t abHypercall[] = { 0x0F, 0x01, 0xD9 };   /* VMMCALL */
-        if (RT_LIKELY(cbBuf >= sizeof(abHypercall)))
-        {
-            memcpy(pvBuf, abHypercall, sizeof(abHypercall));
-            *pcbWritten = sizeof(abHypercall);
-            return VINF_SUCCESS;
-        }
-        return VERR_BUFFER_OVERFLOW;
-    }
+
+/**
+ * Notifies HM that paravirtualized hypercalls are now disabled.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ */
+VMM_INT_DECL(void) HMHypercallsDisable(PVMCPU pVCpu)
+{
+    pVCpu->hm.s.fHypercallsEnabled = false;
+}
+
+
+/**
+ * Notifies HM that GIM provider wants to trap #UD.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ */
+VMM_INT_DECL(void) HMTrapXcptUDForGIMEnable(PVMCPU pVCpu)
+{
+    pVCpu->hm.s.fGIMTrapXcptUD = true;
+    HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+}
+
+
+/**
+ * Notifies HM that GIM provider no longer wants to trap #UD.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ */
+VMM_INT_DECL(void) HMTrapXcptUDForGIMDisable(PVMCPU pVCpu)
+{
+    pVCpu->hm.s.fGIMTrapXcptUD = false;
+    HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
 }
 
diff --git a/src/VBox/VMM/VMMAll/IEMAll.cpp b/src/VBox/VMM/VMMAll/IEMAll.cpp
index 4024ad0..fa282bc 100644
--- a/src/VBox/VMM/VMMAll/IEMAll.cpp
+++ b/src/VBox/VMM/VMMAll/IEMAll.cpp
@@ -188,15 +188,6 @@ typedef IEMSELDESC *PIEMSELDESC;
 /*******************************************************************************
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-/** @name IEM status codes.
- *
- * Not quite sure how this will play out in the end, just aliasing safe status
- * codes for now.
- *
- * @{ */
-#define VINF_IEM_RAISED_XCPT    VINF_EM_RESCHEDULE
-/** @} */
-
 /** Temporary hack to disable the double execution.  Will be removed in favor
  * of a dedicated execution mode in EM. */
 //#define IEM_VERIFICATION_MODE_NO_REM
@@ -295,39 +286,18 @@ typedef IEMSELDESC *PIEMSELDESC;
 #define IEM_IS_REAL_MODE(a_pIemCpu)         (CPUMIsGuestInRealModeEx((a_pIemCpu)->CTX_SUFF(pCtx)))
 
 /**
- * Tests if an AMD CPUID feature (extended) is marked present - ECX.
- */
-#define IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(a_fEcx)    iemRegIsAmdCpuIdFeaturePresent(pIemCpu, 0, (a_fEcx))
-
-/**
- * Tests if an AMD CPUID feature (extended) is marked present - EDX.
- */
-#define IEM_IS_AMD_CPUID_FEATURE_PRESENT_EDX(a_fEdx)    iemRegIsAmdCpuIdFeaturePresent(pIemCpu, (a_fEdx), 0)
-
-/**
- * Tests if at least on of the specified AMD CPUID features (extended) are
- * marked present.
- */
-#define IEM_IS_AMD_CPUID_FEATURES_ANY_PRESENT(a_fEdx, a_fEcx)   iemRegIsAmdCpuIdFeaturePresent(pIemCpu, (a_fEdx), (a_fEcx))
-
-/**
- * Checks if an Intel CPUID feature is present.
- */
-#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(a_fEdx)  \
-    (   ((a_fEdx) & (X86_CPUID_FEATURE_EDX_TSC | 0)) \
-     || iemRegIsIntelCpuIdFeaturePresent(pIemCpu, (a_fEdx), 0) )
-
-/**
- * Checks if an Intel CPUID feature is present.
+ * Returns a (const) pointer to the CPUMFEATURES for the guest CPU.
+ * @returns PCCPUMFEATURES
+ * @param   a_pIemCpu       The IEM state of the current CPU.
  */
-#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(a_fEcx)  \
-    ( iemRegIsIntelCpuIdFeaturePresent(pIemCpu, 0, (a_fEcx)) )
+#define IEM_GET_GUEST_CPU_FEATURES(a_pIemCpu) (&(IEMCPU_TO_VM(a_pIemCpu)->cpum.ro.GuestFeatures))
 
 /**
- * Checks if an Intel CPUID feature is present in the host CPU.
+ * Returns a (const) pointer to the CPUMFEATURES for the host CPU.
+ * @returns PCCPUMFEATURES
+ * @param   a_pIemCpu       The IEM state of the current CPU.
  */
-#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(a_fEdx)  \
-    ( (a_fEdx) & pIemCpu->fHostCpuIdStdFeaturesEdx )
+#define IEM_GET_HOST_CPU_FEATURES(a_pIemCpu)  (&(IEMCPU_TO_VM(a_pIemCpu)->cpum.ro.HostFeatures))
 
 /**
  * Evaluates to true if we're presenting an Intel CPU to the guest.
@@ -1126,6 +1096,7 @@ static VBOXSTRICTRC iemOpcodeFetchMoreBytes(PIEMCPU pIemCpu, size_t cbMin)
         cbToTryRead = cbLeftOnPage;
     if (cbToTryRead > sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode)
         cbToTryRead = sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode;
+/** @todo r=bird: Convert assertion into undefined opcode exception? */
     Assert(cbToTryRead >= cbMin - cbLeft); /* ASSUMPTION based on iemInitDecoderAndPrefetchOpcodes. */
 
 #ifdef VBOX_WITH_RAW_MODE_NOT_R0
@@ -1221,12 +1192,13 @@ DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU8Slow(PIEMCPU pIemCpu, uin
 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PIEMCPU pIemCpu, uint8_t *pu8)
 {
     uint8_t const offOpcode = pIemCpu->offOpcode;
-    if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
-        return iemOpcodeGetNextU8Slow(pIemCpu, pu8);
-
-    *pu8 = pIemCpu->abOpcode[offOpcode];
-    pIemCpu->offOpcode = offOpcode + 1;
-    return VINF_SUCCESS;
+    if (RT_LIKELY(offOpcode < pIemCpu->cbOpcode))
+    {
+        *pu8 = pIemCpu->abOpcode[offOpcode];
+        pIemCpu->offOpcode = offOpcode + 1;
+        return VINF_SUCCESS;
+    }
+    return iemOpcodeGetNextU8Slow(pIemCpu, pu8);
 }
 
 
@@ -3879,6 +3851,10 @@ iemRaiseXcptOrInt(PIEMCPU     pIemCpu,
                   uint64_t    uCr2)
 {
     PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
+#ifdef IN_RING0
+    int rc = HMR0EnsureCompleteBasicContext(IEMCPU_TO_VMCPU(pIemCpu), pCtx);
+    AssertRCReturn(rc, rc);
+#endif
 
     /*
      * Perform the V8086 IOPL check and upgrade the fault without nesting.
@@ -4632,24 +4608,6 @@ static uint64_t iemGRegFetchU64(PIEMCPU pIemCpu, uint8_t iReg)
 
 
 /**
- * Is the FPU state in FXSAVE format or not.
- *
- * @returns true if it is, false if it's in FNSAVE.
- * @param   pVCpu               Pointer to the VMCPU.
- */
-DECLINLINE(bool) iemFRegIsFxSaveFormat(PIEMCPU pIemCpu)
-{
-#ifdef RT_ARCH_AMD64
-    NOREF(pIemCpu);
-    return true;
-#else
-    NOREF(pIemCpu); /// @todo return pVCpu->pVMR3->cpum.s.CPUFeatures.edx.u1FXSR;
-    return true;
-#endif
-}
-
-
-/**
  * Adds a 8-bit signed jump offset to RIP/EIP/IP.
  *
  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
@@ -5127,46 +5085,6 @@ DECLINLINE(RTGCPTR) iemRegGetRspForPopEx(PCIEMCPU pIemCpu, PCCPUMCTX pCtx, PRTUI
     return GCPtrTop;
 }
 
-
-/**
- * Checks if an Intel CPUID feature bit is set.
- *
- * @returns true / false.
- *
- * @param   pIemCpu             The IEM per CPU data.
- * @param   fEdx                The EDX bit to test, or 0 if ECX.
- * @param   fEcx                The ECX bit to test, or 0 if EDX.
- * @remarks Used via IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX,
- *          IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX and others.
- */
-static bool iemRegIsIntelCpuIdFeaturePresent(PIEMCPU pIemCpu, uint32_t fEdx, uint32_t fEcx)
-{
-    uint32_t uEax, uEbx, uEcx, uEdx;
-    CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x00000001, 0, &uEax, &uEbx, &uEcx, &uEdx);
-    return (fEcx && (uEcx & fEcx))
-        || (fEdx && (uEdx & fEdx));
-}
-
-
-/**
- * Checks if an AMD CPUID feature bit is set.
- *
- * @returns true / false.
- *
- * @param   pIemCpu             The IEM per CPU data.
- * @param   fEdx                The EDX bit to test, or 0 if ECX.
- * @param   fEcx                The ECX bit to test, or 0 if EDX.
- * @remarks Used via IEM_IS_AMD_CPUID_FEATURE_PRESENT_EDX,
- *          IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX and others.
- */
-static bool iemRegIsAmdCpuIdFeaturePresent(PIEMCPU pIemCpu, uint32_t fEdx, uint32_t fEcx)
-{
-    uint32_t uEax, uEbx, uEcx, uEdx;
-    CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 0x80000001, 0, &uEax, &uEbx, &uEcx, &uEdx);
-    return (fEcx && (uEcx & fEcx))
-        || (fEdx && (uEdx & fEdx));
-}
-
 /** @}  */
 
 
@@ -8335,7 +8253,7 @@ static VBOXSTRICTRC iemMemMarkSelDescAccessed(PIEMCPU pIemCpu, uint16_t uSel)
     do { \
         if (   (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_EM) \
             || !(pIemCpu->CTX_SUFF(pCtx)->cr4 & X86_CR4_OSFXSR) \
-            || !IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE2) ) \
+            || !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fSse2) \
             return iemRaiseUndefinedOpcode(pIemCpu); \
         if (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_TS) \
             return iemRaiseDeviceNotAvailable(pIemCpu); \
@@ -8343,7 +8261,7 @@ static VBOXSTRICTRC iemMemMarkSelDescAccessed(PIEMCPU pIemCpu, uint16_t uSel)
 #define IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT() \
     do { \
         if (   ((pIemCpu)->CTX_SUFF(pCtx)->cr0 & X86_CR0_EM) \
-            || !IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_MMX) ) \
+            || !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMmx) \
             return iemRaiseUndefinedOpcode(pIemCpu); \
         if (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_TS) \
             return iemRaiseDeviceNotAvailable(pIemCpu); \
@@ -8351,8 +8269,8 @@ static VBOXSTRICTRC iemMemMarkSelDescAccessed(PIEMCPU pIemCpu, uint16_t uSel)
 #define IEM_MC_MAYBE_RAISE_MMX_RELATED_XCPT_CHECK_SSE_OR_MMXEXT() \
     do { \
         if (   ((pIemCpu)->CTX_SUFF(pCtx)->cr0 & X86_CR0_EM) \
-            || (   !IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE) \
-                && !IEM_IS_AMD_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_AMD_FEATURE_EDX_AXMMX) ) ) \
+            || (   !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fSse \
+                && !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fAmdMmxExts) ) \
             return iemRaiseUndefinedOpcode(pIemCpu); \
         if (pIemCpu->CTX_SUFF(pCtx)->cr0 & X86_CR0_TS) \
             return iemRaiseDeviceNotAvailable(pIemCpu); \
@@ -11315,3 +11233,93 @@ VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IE
     return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
 }
 
+
+
+/**
+ * Interface for HM and EM to write to a CRx register.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu       The cross context per virtual CPU structure.
+ * @param   cbInstr     The instruction length in bytes.
+ * @param   iCrReg      The control register number (destination).
+ * @param   iGReg       The general purpose register number (source).
+ *
+ * @remarks In ring-0 not all of the state needs to be synced in.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxWrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iCrReg, uint8_t iGReg)
+{
+    AssertReturn(cbInstr - 2U <= 15U - 2U, VERR_IEM_INVALID_INSTR_LENGTH);
+    Assert(iCrReg < 16);
+    Assert(iGReg < 16);
+
+    PIEMCPU pIemCpu = &pVCpu->iem.s;
+    iemInitExec(pIemCpu, false /*fBypassHandlers*/);
+    VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_2(iemCImpl_mov_Cd_Rd, iCrReg, iGReg);
+    return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
+}
+
+
+/**
+ * Interface for HM and EM to read from a CRx register.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu       The cross context per virtual CPU structure.
+ * @param   cbInstr     The instruction length in bytes.
+ * @param   iGReg       The general purpose register number (destination).
+ * @param   iCrReg      The control register number (source).
+ *
+ * @remarks In ring-0 not all of the state needs to be synced in.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxRead(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iGReg, uint8_t iCrReg)
+{
+    AssertReturn(cbInstr - 2U <= 15U - 2U, VERR_IEM_INVALID_INSTR_LENGTH);
+    Assert(iCrReg < 16);
+    Assert(iGReg < 16);
+
+    PIEMCPU pIemCpu = &pVCpu->iem.s;
+    iemInitExec(pIemCpu, false /*fBypassHandlers*/);
+    VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_2(iemCImpl_mov_Rd_Cd, iGReg, iCrReg);
+    return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
+}
+
+
+/**
+ * Interface for HM and EM to clear the CR0[TS] bit.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu       The cross context per virtual CPU structure.
+ * @param   cbInstr     The instruction length in bytes.
+ *
+ * @remarks In ring-0 not all of the state needs to be synced in.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedClts(PVMCPU pVCpu, uint8_t cbInstr)
+{
+    AssertReturn(cbInstr - 2U <= 15U - 2U, VERR_IEM_INVALID_INSTR_LENGTH);
+
+    PIEMCPU pIemCpu = &pVCpu->iem.s;
+    iemInitExec(pIemCpu, false /*fBypassHandlers*/);
+    VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_0(iemCImpl_clts);
+    return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
+}
+
+
+/**
+ * Interface for HM and EM to emulate the LMSW instruction (loads CR0).
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu       The cross context per virtual CPU structure.
+ * @param   cbInstr     The instruction length in bytes.
+ * @param   uValue      The value to load into CR0.
+ *
+ * @remarks In ring-0 not all of the state needs to be synced in.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uValue)
+{
+    AssertReturn(cbInstr - 3U <= 15U - 3U, VERR_IEM_INVALID_INSTR_LENGTH);
+
+    PIEMCPU pIemCpu = &pVCpu->iem.s;
+    iemInitExec(pIemCpu, false /*fBypassHandlers*/);
+    VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_1(iemCImpl_lmsw, uValue);
+    return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
+}
+
diff --git a/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h b/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
index 1f54a1d..db47eb1 100644
--- a/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
+++ b/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
@@ -4980,8 +4980,8 @@ IEM_CIMPL_DEF_2(iemCImpl_load_CrX, uint8_t, iCrReg, uint64_t, uNewCrX)
                             | X86_CR4_OSXMMEEXCPT;
             //if (xxx)
             //    fValid |= X86_CR4_VMXE;
-            //if (xxx)
-            //    fValid |= X86_CR4_OSXSAVE;
+            if (IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fXSaveRstor)
+                fValid |= X86_CR4_OSXSAVE;
             if (uNewCrX & ~(uint64_t)fValid)
             {
                 Log(("Trying to set reserved CR4 bits: NewCR4=%#llx InvalidBits=%#llx\n", uNewCrX, uNewCrX & ~(uint64_t)fValid));
@@ -5334,7 +5334,7 @@ IEM_CIMPL_DEF_0(iemCImpl_rdtsc)
     /*
      * Check preconditions.
      */
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_TSC))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fTsc)
         return iemRaiseUndefinedOpcode(pIemCpu);
 
     if (   (pCtx->cr4 & X86_CR4_TSD)
@@ -5369,7 +5369,7 @@ IEM_CIMPL_DEF_0(iemCImpl_rdmsr)
     /*
      * Check preconditions.
      */
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_MSR))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMsr)
         return iemRaiseUndefinedOpcode(pIemCpu);
     if (pIemCpu->uCpl != 0)
         return iemRaiseGeneralProtectionFault0(pIemCpu);
@@ -5418,7 +5418,7 @@ IEM_CIMPL_DEF_0(iemCImpl_wrmsr)
     /*
      * Check preconditions.
      */
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_MSR))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMsr)
         return iemRaiseUndefinedOpcode(pIemCpu);
     if (pIemCpu->uCpl != 0)
         return iemRaiseGeneralProtectionFault0(pIemCpu);
@@ -5724,7 +5724,7 @@ IEM_CIMPL_DEF_1(iemCImpl_monitor, uint8_t, iEffSeg)
         Log2(("monitor: CPL != 0\n"));
         return iemRaiseUndefinedOpcode(pIemCpu); /** @todo MSR[0xC0010015].MonMwaitUserEn if we care. */
     }
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_FEATURE_ECX_MONITOR))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMonitorMWait)
     {
         Log2(("monitor: Not in CPUID\n"));
         return iemRaiseUndefinedOpcode(pIemCpu);
@@ -5780,7 +5780,7 @@ IEM_CIMPL_DEF_0(iemCImpl_mwait)
          *        EFLAGS.VM then.) */
         return iemRaiseUndefinedOpcode(pIemCpu);
     }
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_FEATURE_ECX_MONITOR))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMonitorMWait)
     {
         Log2(("mwait: Not in CPUID\n"));
         return iemRaiseUndefinedOpcode(pIemCpu);
@@ -6043,31 +6043,16 @@ IEM_CIMPL_DEF_1(iemCImpl_finit, bool, fCheckXcpts)
      */
 
     PX86XSAVEAREA pXState = pCtx->CTX_SUFF(pXState);
-    if (iemFRegIsFxSaveFormat(pIemCpu))
-    {
-        pXState->x87.FCW   = 0x37f;
-        pXState->x87.FSW   = 0;
-        pXState->x87.FTW   = 0x00;         /* 0 - empty. */
-        pXState->x87.FPUDP = 0;
-        pXState->x87.DS    = 0; //??
-        pXState->x87.Rsrvd2= 0;
-        pXState->x87.FPUIP = 0;
-        pXState->x87.CS    = 0; //??
-        pXState->x87.Rsrvd1= 0;
-        pXState->x87.FOP   = 0;
-    }
-    else
-    {
-        PX86FPUSTATE pFpu = (PX86FPUSTATE)&pXState->x87;
-        pFpu->FCW       = 0x37f;
-        pFpu->FSW       = 0;
-        pFpu->FTW       = 0xffff;       /* 11 - empty */
-        pFpu->FPUOO     = 0; //??
-        pFpu->FPUOS     = 0; //??
-        pFpu->FPUIP     = 0;
-        pFpu->CS        = 0; //??
-        pFpu->FOP       = 0;
-    }
+    pXState->x87.FCW   = 0x37f;
+    pXState->x87.FSW   = 0;
+    pXState->x87.FTW   = 0x00;         /* 0 - empty. */
+    pXState->x87.FPUDP = 0;
+    pXState->x87.DS    = 0; //??
+    pXState->x87.Rsrvd2= 0;
+    pXState->x87.FPUIP = 0;
+    pXState->x87.CS    = 0; //??
+    pXState->x87.Rsrvd1= 0;
+    pXState->x87.FOP   = 0;
 
     iemHlpUsedFpu(pIemCpu);
     iemRegAddToRipAndClearRF(pIemCpu, cbInstr);
@@ -6103,7 +6088,6 @@ IEM_CIMPL_DEF_3(iemCImpl_fxsave, uint8_t, iEffSeg, RTGCPTR, GCPtrEff, IEMMODE, e
             return iemRaiseAlignmentCheckException(pIemCpu);
         return iemRaiseGeneralProtectionFault0(pIemCpu);
     }
-    AssertReturn(iemFRegIsFxSaveFormat(pIemCpu), VERR_IEM_IPE_2);
 
     /*
      * Access the memory.
@@ -6208,7 +6192,6 @@ IEM_CIMPL_DEF_3(iemCImpl_fxrstor, uint8_t, iEffSeg, RTGCPTR, GCPtrEff, IEMMODE,
             return iemRaiseAlignmentCheckException(pIemCpu);
         return iemRaiseGeneralProtectionFault0(pIemCpu);
     }
-    AssertReturn(iemFRegIsFxSaveFormat(pIemCpu), VERR_IEM_IPE_2);
 
     /*
      * Access the memory.
diff --git a/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h b/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
index 3d7584c..3dffd69 100644
--- a/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
+++ b/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
@@ -1307,8 +1307,7 @@ FNIEMOP_STUB(iemOp_ud2);
 FNIEMOP_DEF(iemOp_nop_Ev_GrpP)
 {
     /* AMD prefetch group, Intel implements this as NOP Ev (and so do we). */
-    if (!IEM_IS_AMD_CPUID_FEATURES_ANY_PRESENT(X86_CPUID_EXT_FEATURE_EDX_LONG_MODE | X86_CPUID_AMD_FEATURE_EDX_3DNOW,
-                                               X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->f3DNowPrefetch)
     {
         IEMOP_MNEMONIC("GrpP");
         return IEMOP_RAISE_INVALID_OPCODE();
@@ -1425,7 +1424,7 @@ FNIEMOP_STUB(iemOp_3Dnow_pavgusb_PQ_Qq);
 /** Opcode 0x0f 0x0f. */
 FNIEMOP_DEF(iemOp_3Dnow)
 {
-    if (!IEM_IS_AMD_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_AMD_FEATURE_EDX_3DNOW))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->f3DNow)
     {
         IEMOP_MNEMONIC("3Dnow");
         return IEMOP_RAISE_INVALID_OPCODE();
@@ -1555,7 +1554,7 @@ FNIEMOP_DEF(iemOp_mov_Rd_Cd)
     if (pIemCpu->fPrefixes & IEM_OP_PRF_LOCK)
     {
         /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
-        if (!IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_AMD_FEATURE_ECX_CR8L))
+        if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMovCr8In32Bit)
             return IEMOP_RAISE_INVALID_OPCODE(); /* #UD takes precedence over #GP(), see test. */
         iCrReg |= 8;
     }
@@ -1601,7 +1600,7 @@ FNIEMOP_DEF(iemOp_mov_Cd_Rd)
     if (pIemCpu->fPrefixes & IEM_OP_PRF_LOCK)
     {
         /* The lock prefix can be used to encode CR8 accesses on some CPUs. */
-        if (!IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_AMD_FEATURE_ECX_CR8L))
+        if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fMovCr8In32Bit)
             return IEMOP_RAISE_INVALID_OPCODE(); /* #UD takes precedence over #GP(), see test. */
         iCrReg |= 8;
     }
@@ -4923,7 +4922,7 @@ FNIEMOP_DEF(iemOp_shrd_Ev_Gv_CL)
 FNIEMOP_DEF_1(iemOp_Grp15_fxsave,   uint8_t, bRm)
 {
     IEMOP_MNEMONIC("fxsave m512");
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_FXSR))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fFxSaveRstor)
         return IEMOP_RAISE_INVALID_OPCODE();
 
     IEM_MC_BEGIN(3, 1);
@@ -4943,7 +4942,7 @@ FNIEMOP_DEF_1(iemOp_Grp15_fxsave,   uint8_t, bRm)
 FNIEMOP_DEF_1(iemOp_Grp15_fxrstor,  uint8_t, bRm)
 {
     IEMOP_MNEMONIC("fxrstor m512");
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_FXSR))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fFxSaveRstor)
         return IEMOP_RAISE_INVALID_OPCODE();
 
     IEM_MC_BEGIN(3, 1);
@@ -4983,11 +4982,11 @@ FNIEMOP_DEF_1(iemOp_Grp15_lfence,   uint8_t, bRm)
 {
     IEMOP_MNEMONIC("lfence");
     IEMOP_HLP_NO_LOCK_PREFIX();
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE2))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fSse2)
         return IEMOP_RAISE_INVALID_OPCODE();
 
     IEM_MC_BEGIN(0, 0);
-    if (IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(X86_CPUID_FEATURE_EDX_SSE2))
+    if (IEM_GET_HOST_CPU_FEATURES(pIemCpu)->fSse2)
         IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_lfence);
     else
         IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
@@ -5002,11 +5001,11 @@ FNIEMOP_DEF_1(iemOp_Grp15_mfence,   uint8_t, bRm)
 {
     IEMOP_MNEMONIC("mfence");
     IEMOP_HLP_NO_LOCK_PREFIX();
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE2))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fSse2)
         return IEMOP_RAISE_INVALID_OPCODE();
 
     IEM_MC_BEGIN(0, 0);
-    if (IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(X86_CPUID_FEATURE_EDX_SSE2))
+    if (IEM_GET_HOST_CPU_FEATURES(pIemCpu)->fSse2)
         IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_mfence);
     else
         IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
@@ -5021,11 +5020,11 @@ FNIEMOP_DEF_1(iemOp_Grp15_sfence,   uint8_t, bRm)
 {
     IEMOP_MNEMONIC("sfence");
     IEMOP_HLP_NO_LOCK_PREFIX();
-    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_SSE2))
+    if (!IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fSse2)
         return IEMOP_RAISE_INVALID_OPCODE();
 
     IEM_MC_BEGIN(0, 0);
-    if (IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(X86_CPUID_FEATURE_EDX_SSE2))
+    if (IEM_GET_HOST_CPU_FEATURES(pIemCpu)->fSse2)
         IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_sfence);
     else
         IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
@@ -10550,7 +10549,7 @@ FNIEMOP_DEF(iemOp_sahf)
     IEMOP_MNEMONIC("sahf");
     IEMOP_HLP_NO_LOCK_PREFIX();
     if (   pIemCpu->enmCpuMode == IEMMODE_64BIT
-        && !IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF))
+        && !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fLahfSahf)
         return IEMOP_RAISE_INVALID_OPCODE();
     IEM_MC_BEGIN(0, 2);
     IEM_MC_LOCAL(uint32_t, u32Flags);
@@ -10574,7 +10573,7 @@ FNIEMOP_DEF(iemOp_lahf)
     IEMOP_MNEMONIC("lahf");
     IEMOP_HLP_NO_LOCK_PREFIX();
     if (   pIemCpu->enmCpuMode == IEMMODE_64BIT
-        && !IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF))
+        && !IEM_GET_GUEST_CPU_FEATURES(pIemCpu)->fLahfSahf)
         return IEMOP_RAISE_INVALID_OPCODE();
     IEM_MC_BEGIN(0, 1);
     IEM_MC_LOCAL(uint8_t, u8Flags);
diff --git a/src/VBox/VMM/VMMAll/VMMAll.cpp b/src/VBox/VMM/VMMAll/VMMAll.cpp
index f9c325e..ae7fc1b 100644
--- a/src/VBox/VMM/VMMAll/VMMAll.cpp
+++ b/src/VBox/VMM/VMMAll/VMMAll.cpp
@@ -23,6 +23,7 @@
 #include <VBox/vmm/vmm.h>
 #include "VMMInternal.h"
 #include <VBox/vmm/vm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/vmcpuset.h>
 #include <VBox/param.h>
 #include <iprt/thread.h>
@@ -390,3 +391,76 @@ uint32_t vmmGetBuildType(void)
     return uRet;
 }
 
+
+/**
+ * Patches the instructions necessary for making a hypercall to the hypervisor.
+ * Used by GIM.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pvBuf       The buffer in the hypercall page(s) to be patched.
+ * @param   cbBuf       The size of the buffer.
+ * @param   pcbWritten  Where to store the number of bytes patched. This
+ *                      is reliably updated only when this function returns
+ *                      VINF_SUCCESS.
+ */
+VMM_INT_DECL(int) VMMPatchHypercall(PVM pVM, void *pvBuf, size_t cbBuf, size_t *pcbWritten)
+{
+    AssertReturn(pvBuf, VERR_INVALID_POINTER);
+    AssertReturn(pcbWritten, VERR_INVALID_POINTER);
+
+    if (ASMIsAmdCpu())
+    {
+        uint8_t abHypercall[] = { 0x0F, 0x01, 0xD9 };   /* VMMCALL */
+        if (RT_LIKELY(cbBuf >= sizeof(abHypercall)))
+        {
+            memcpy(pvBuf, abHypercall, sizeof(abHypercall));
+            *pcbWritten = sizeof(abHypercall);
+            return VINF_SUCCESS;
+        }
+        return VERR_BUFFER_OVERFLOW;
+    }
+    else
+    {
+        AssertReturn(ASMIsIntelCpu() || ASMIsViaCentaurCpu(), VERR_UNSUPPORTED_CPU);
+        uint8_t abHypercall[] = { 0x0F, 0x01, 0xC1 };   /* VMCALL */
+        if (RT_LIKELY(cbBuf >= sizeof(abHypercall)))
+        {
+            memcpy(pvBuf, abHypercall, sizeof(abHypercall));
+            *pcbWritten = sizeof(abHypercall);
+            return VINF_SUCCESS;
+        }
+        return VERR_BUFFER_OVERFLOW;
+    }
+}
+
+
+/**
+ * Notifies VMM that paravirtualized hypercalls are now enabled.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ */
+VMM_INT_DECL(void) VMMHypercallsEnable(PVMCPU pVCpu)
+{
+    /* If there is anything to do for raw-mode, do it here. */
+#ifndef IN_RC
+    if (HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+        HMHypercallsEnable(pVCpu);
+#endif
+}
+
+
+/**
+ * Notifies VMM that paravirtualized hypercalls are now disabled.
+ *
+ * @param   pVCpu   Pointer to the VMCPU.
+ */
+VMM_INT_DECL(void) VMMHypercallsDisable(PVMCPU pVCpu)
+{
+    /* If there is anything to do for raw-mode, do it here. */
+#ifndef IN_RC
+    if (HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+        HMHypercallsDisable(pVCpu);
+#endif
+}
+
diff --git a/src/VBox/VMM/VMMR0/CPUMR0A.asm b/src/VBox/VMM/VMMR0/CPUMR0A.asm
index 0308536..975c8d4 100644
--- a/src/VBox/VMM/VMMR0/CPUMR0A.asm
+++ b/src/VBox/VMM/VMMR0/CPUMR0A.asm
@@ -40,6 +40,13 @@
 %define CS_OFF_IN_X86FXSTATE    0ch
 %define DS_OFF_IN_X86FXSTATE    14h
 
+;; For numeric expressions
+%ifdef RT_ARCH_AMD64
+ %define CPUMR0_IS_AMD64        1
+%else
+ %define CPUMR0_IS_AMD64        0
+%endif
+
 
 ;*******************************************************************************
 ;* External Symbols                                                            *
@@ -106,82 +113,378 @@ BEGINCODE
 %endif ; Unused.
 
 
+;;
+; Clears CR0.TS and CR0.EM if necessary, saving the previous result.
+;
+; This is used to avoid FPU exceptions when touching the FPU state.
+;
+; @param    %1      Register to save the old CR0 in (pass to RESTORE_CR0).
+; @param    %2      Temporary scratch register.
+; @uses     EFLAGS, CR0
+;
+%macro SAVE_CR0_CLEAR_FPU_TRAPS 2
+        xor     %1, %1
+        mov     %2, cr0
+        test    %2, X86_CR0_TS | X86_CR0_EM ; Make sure its safe to access the FPU state.
+        jz      %%skip_cr0_write
+        mov     %1, %2                  ; Save old CR0
+        and     %2, ~(X86_CR0_TS | X86_CR0_EM)
+        mov     cr0, %2
+%%skip_cr0_write:
+%endmacro
+
+;;
+; Restore CR0.TS and CR0.EM state if SAVE_CR0_CLEAR_FPU_TRAPS change it.
+;
+; @param    %1      The register that SAVE_CR0_CLEAR_FPU_TRAPS saved the old CR0 in.
+;
+%macro RESTORE_CR0 1
+        cmp     %1, 0
+        je      %%skip_cr0_restore
+        mov     cr0, %1
+%%skip_cr0_restore:
+%endmacro
+
+
+;;
+; Saves the host state.
+;
+; @uses     rax, rdx
+; @param    pCpumCpu    Define for the register containing the CPUMCPU pointer.
+; @param    pXState     Define for the regsiter containing the extended state pointer.
+;
+%macro CPUMR0_SAVE_HOST 0
+        ;
+        ; Load a couple of registers we'll use later in all branches.
+        ;
+        mov     pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
+        mov     eax, [pCpumCpu + CPUMCPU.Host.fXStateMask]
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+        ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
+        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
+        jz      %%host_legacy_mode
+        db      0xea                    ; jmp far .sixtyfourbit_mode
+        dd      %%host_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+BITS 64
+%%host_sixtyfourbit_mode:
+        or      eax, eax
+        jz      %%host_sixtyfourbit_fxsave
+
+        ; XSAVE
+        mov     edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
+        o64 xsave [pXState]
+        jmp     %%host_sixtyfourbit_done
+
+        ; FXSAVE
+%%host_sixtyfourbit_fxsave:
+        o64 fxsave [pXState]
+
+%%host_sixtyfourbit_done:
+        jmp far [%%host_fpret wrt rip]
+%%host_fpret:                           ; 16:32 Pointer to %%host_done.
+        dd      %%host_done, NAME(SUPR0AbsKernelCS)
+BITS 32
+
+%%host_legacy_mode:
+%endif
+
+        ;
+        ; XSAVE or FXSAVE?
+        ;
+        or      eax, eax
+        jz      %%host_fxsave
+
+        ; XSAVE
+        mov     edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
+%ifdef RT_ARCH_AMD64
+        o64 xsave [pXState]
+%else
+        xsave   [pXState]
+%endif
+        jmp     %%host_done
+
+        ; FXSAVE
+%%host_fxsave:
+%ifdef RT_ARCH_AMD64
+        o64 fxsave [pXState]            ; Use explicit REX prefix. See @bugref{6398}.
+%else
+        fxsave  [pXState]
+%endif
+
+%%host_done:
+%endmacro ; CPUMR0_SAVE_HOST
+
+
+;;
+; Loads the host state.
+;
+; @uses     rax, rdx
+; @param    pCpumCpu    Define for the register containing the CPUMCPU pointer.
+; @param    pXState     Define for the regsiter containing the extended state pointer.
+;
+%macro CPUMR0_LOAD_HOST 0
+        ;
+        ; Load a couple of registers we'll use later in all branches.
+        ;
+        mov     pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
+        mov     eax, [pCpumCpu + CPUMCPU.Host.fXStateMask]
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+        ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
+        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
+        jz      %%host_legacy_mode
+        db      0xea                    ; jmp far .sixtyfourbit_mode
+        dd      %%host_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+BITS 64
+%%host_sixtyfourbit_mode:
+        or      eax, eax
+        jz      %%host_sixtyfourbit_fxrstor
+
+        ; XRSTOR
+        mov     edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
+        o64 xrstor [pXState]
+        jmp     %%host_sixtyfourbit_done
+
+        ; FXRSTOR
+%%host_sixtyfourbit_fxrstor:
+        o64 fxrstor [pXState]
+
+%%host_sixtyfourbit_done:
+        jmp far [%%host_fpret wrt rip]
+%%host_fpret:                           ; 16:32 Pointer to %%host_done.
+        dd      %%host_done, NAME(SUPR0AbsKernelCS)
+BITS 32
+
+%%host_legacy_mode:
+%endif
+
+        ;
+        ; XRSTOR or FXRSTOR?
+        ;
+        or      eax, eax
+        jz      %%host_fxrstor
+
+        ; XRSTOR
+        mov     edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
+%ifdef RT_ARCH_AMD64
+        o64 xrstor [pXState]
+%else
+        xrstor  [pXState]
+%endif
+        jmp     %%host_done
+
+        ; FXRSTOR
+%%host_fxrstor:
+%ifdef RT_ARCH_AMD64
+        o64 fxrstor [pXState]           ; Use explicit REX prefix. See @bugref{6398}.
+%else
+        fxrstor [pXState]
+%endif
+
+%%host_done:
+%endmacro ; CPUMR0_LOAD_HOST
+
+
+
 ;; Macro for FXSAVE for the guest FPU but tries to figure out whether to
 ;  save the 32-bit FPU state or 64-bit FPU state.
 ;
 ; @param    %1      Pointer to CPUMCPU.
 ; @param    %2      Pointer to XState.
+; @param    %3      Force AMD64
 ; @uses     xAX, xDX, EFLAGS, 20h of stack.
 ;
-%macro SAVE_32_OR_64_FPU 2
-        o64 fxsave [%2]
+%macro SAVE_32_OR_64_FPU 3
+%if CPUMR0_IS_AMD64 || %3
+        ; Save the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
+        test    dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
+        jnz     short %%save_long_mode_guest
+%endif
+        fxsave  [pXState]
+%if CPUMR0_IS_AMD64 || %3
+        jmp     %%save_done_32bit_cs_ds
+
+%%save_long_mode_guest:
+        o64 fxsave [pXState]
 
         xor     edx, edx
-        cmp     dword [%2 + CS_OFF_IN_X86FXSTATE], 0
+        cmp     dword [pXState + CS_OFF_IN_X86FXSTATE], 0
         jne     short %%save_done
 
         sub     rsp, 20h                ; Only need 1ch bytes but keep stack aligned otherwise we #GP(0).
         fnstenv [rsp]
         movzx   eax, word [rsp + 10h]
-        mov     [%2 + CS_OFF_IN_X86FXSTATE], eax
+        mov     [pXState + CS_OFF_IN_X86FXSTATE], eax
         movzx   eax, word [rsp + 18h]
         add     rsp, 20h
-        mov     [%2 + DS_OFF_IN_X86FXSTATE], eax
+        mov     [pXState + DS_OFF_IN_X86FXSTATE], eax
+%endif
+%%save_done_32bit_cs_ds:
         mov     edx, X86_FXSTATE_RSVD_32BIT_MAGIC
-
 %%save_done:
-        mov     dword [%2 + X86_OFF_FXSTATE_RSVD], edx
-%endmacro
+        mov     dword [pXState + X86_OFF_FXSTATE_RSVD], edx
+%endmacro ; SAVE_32_OR_64_FPU
+
+
+;;
+; Save the guest state.
+;
+; @uses     rax, rdx
+; @param    pCpumCpu    Define for the register containing the CPUMCPU pointer.
+; @param    pXState     Define for the regsiter containing the extended state pointer.
+;
+%macro CPUMR0_SAVE_GUEST 0
+        ;
+        ; Load a couple of registers we'll use later in all branches.
+        ;
+        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
+        mov     eax, [pCpumCpu + CPUMCPU.Guest.fXStateMask]
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+        ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
+        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
+        jz      %%guest_legacy_mode
+        db      0xea                    ; jmp far .sixtyfourbit_mode
+        dd      %%guest_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+BITS 64
+%%guest_sixtyfourbit_mode:
+        or      eax, eax
+        jz      %%guest_sixtyfourbit_fxsave
+
+        ; XSAVE
+        mov     edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
+        o64 xsave [pXState]
+        jmp     %%guest_sixtyfourbit_done
+
+        ; FXSAVE
+%%guest_sixtyfourbit_fxsave:
+        SAVE_32_OR_64_FPU pCpumCpu, pXState, 1
+
+%%guest_sixtyfourbit_done:
+        jmp far [%%guest_fpret wrt rip]
+%%guest_fpret:                          ; 16:32 Pointer to %%guest_done.
+        dd      %%guest_done, NAME(SUPR0AbsKernelCS)
+BITS 32
+
+%%guest_legacy_mode:
+%endif
+
+        ;
+        ; XSAVE or FXSAVE?
+        ;
+        or      eax, eax
+        jz      %%guest_fxsave
+
+        ; XSAVE
+        mov     edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
+%ifdef RT_ARCH_AMD64
+        o64 xsave [pXState]
+%else
+        xsave   [pXState]
+%endif
+        jmp     %%guest_done
+
+        ; FXSAVE
+%%guest_fxsave:
+        SAVE_32_OR_64_FPU pCpumCpu, pXState, 0
+
+%%guest_done:
+%endmacro ; CPUMR0_SAVE_GUEST
+
 
 ;;
 ; Wrapper for selecting 32-bit or 64-bit FXRSTOR according to what SAVE_32_OR_64_FPU did.
 ;
 ; @param    %1      Pointer to CPUMCPU.
 ; @param    %2      Pointer to XState.
+; @param    %3      Force AMD64.
 ; @uses     xAX, xDX, EFLAGS
 ;
-%macro RESTORE_32_OR_64_FPU 2
-        cmp     dword [%2 + X86_OFF_FXSTATE_RSVD], X86_FXSTATE_RSVD_32BIT_MAGIC
+%macro RESTORE_32_OR_64_FPU 3
+%if CPUMR0_IS_AMD64 || %3
+        ; Restore the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
+        test    dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
+        jz      %%restore_32bit_fpu
+        cmp     dword [pXState + X86_OFF_FXSTATE_RSVD], X86_FXSTATE_RSVD_32BIT_MAGIC
         jne     short %%restore_64bit_fpu
-        fxrstor [%2]
+%%restore_32bit_fpu:
+%endif
+        fxrstor [pXState]
+%if CPUMR0_IS_AMD64 || %3
+        ; TODO: Restore XMM8-XMM15!
         jmp     short %%restore_fpu_done
 %%restore_64bit_fpu:
-        o64 fxrstor [%2]
+        o64 fxrstor [pXState]
 %%restore_fpu_done:
-%endmacro
+%endif
+%endmacro ; RESTORE_32_OR_64_FPU
 
 
 ;;
-; Clears CR0.TS and CR0.EM if necessary, saving the previous result.
+; Loads the guest state.
 ;
-; This is used to avoid FPU exceptions when touching the FPU state.
+; @uses     rax, rdx
+; @param    pCpumCpu    Define for the register containing the CPUMCPU pointer.
+; @param    pXState     Define for the regsiter containing the extended state pointer.
 ;
-; @param    %1      Register to save the old CR0 in (pass to RESTORE_CR0).
-; @param    %2      Temporary scratch register.
-; @uses     EFLAGS, CR0
-;
-%macro SAVE_CR0_CLEAR_FPU_TRAPS 2
-        xor     %1, %1
-        mov     %2, cr0
-        test    %2, X86_CR0_TS | X86_CR0_EM ; Make sure its safe to access the FPU state.
-        jz      %%skip_cr0_write
-        mov     %1, %2                  ; Save old CR0
-        and     %2, ~(X86_CR0_TS | X86_CR0_EM)
-        mov     cr0, %2
-%%skip_cr0_write:
-%endmacro
+%macro CPUMR0_LOAD_GUEST 0
+        ;
+        ; Load a couple of registers we'll use later in all branches.
+        ;
+        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
+        mov     eax, [pCpumCpu + CPUMCPU.Guest.fXStateMask]
 
-;;
-; Restore CR0.TS and CR0.EM state if SAVE_CR0_CLEAR_FPU_TRAPS change it.
-;
-; @param    %1      The register that SAVE_CR0_CLEAR_FPU_TRAPS saved the old CR0 in.
-;
-%macro RESTORE_CR0 1
-        cmp     %1, 0
-        je      %%skip_cr0_restore
-        mov     cr0, %1
-%%skip_cr0_restore:
-%endmacro
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+        ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
+        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
+        jz      %%guest_legacy_mode
+        db      0xea                    ; jmp far .sixtyfourbit_mode
+        dd      %%guest_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+BITS 64
+%%guest_sixtyfourbit_mode:
+        or      eax, eax
+        jz      %%guest_sixtyfourbit_fxrstor
+
+        ; XRSTOR
+        mov     edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
+        o64 xrstor [pXState]
+        jmp     %%guest_sixtyfourbit_done
+
+        ; FXRSTOR
+%%guest_sixtyfourbit_fxrstor:
+        RESTORE_32_OR_64_FPU pCpumCpu, pXState, 1
+
+%%guest_sixtyfourbit_done:
+        jmp far [%%guest_fpret wrt rip]
+%%guest_fpret:                          ; 16:32 Pointer to %%guest_done.
+        dd      %%guest_done, NAME(SUPR0AbsKernelCS)
+BITS 32
+
+%%guest_legacy_mode:
+%endif
+
+        ;
+        ; XRSTOR or FXRSTOR?
+        ;
+        or      eax, eax
+        jz      %%guest_fxrstor
+
+        ; XRSTOR
+        mov     edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
+%ifdef RT_ARCH_AMD64
+        o64 xrstor [pXState]
+%else
+        xrstor  [pXState]
+%endif
+        jmp     %%guest_done
+
+        ; FXRSTOR
+%%guest_fxrstor:
+        RESTORE_32_OR_64_FPU pCpumCpu, pXState, 0
+
+%%guest_done:
+%endmacro ; CPUMR0_LOAD_GUEST
 
 
 ;;
@@ -218,36 +521,8 @@ BEGINPROC cpumR0SaveHostRestoreGuestFPUState
 
         SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
 
-        ;
-        ; Switch state.
-        ;
-        mov     pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
-        jz      .legacy_mode
-        db      0xea                    ; jmp far .sixtyfourbit_mode
-        dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
-%endif
-
-%ifdef RT_ARCH_AMD64
-        o64 fxsave [pXState]            ; Use explicit REX prefix. See @bugref{6398}.
-
-        ; Restore the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
-        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
-        test    dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
-        jnz     short .fpu_load_32_or_64
-        fxrstor [pXState]
-        jmp     short .fpu_load_done
-.fpu_load_32_or_64:
-        RESTORE_32_OR_64_FPU pCpumCpu, pXState
-.fpu_load_done:
-%else
-        fxsave  [pXState]
-        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
-        fxrstor [pXState]
-%endif
+        CPUMR0_SAVE_HOST
+        CPUMR0_LOAD_GUEST
 
 %ifdef VBOX_WITH_KERNEL_USING_XMM
         ; Restore the non-volatile xmm registers. ASSUMING 64-bit host.
@@ -264,7 +539,6 @@ BEGINPROC cpumR0SaveHostRestoreGuestFPUState
         movdqa  xmm15, [pXState + XMM_OFF_IN_X86FXSTATE + 0f0h]
 %endif
 
-.done:
         RESTORE_CR0 xCX
         or      dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
         popf
@@ -276,28 +550,6 @@ BEGINPROC cpumR0SaveHostRestoreGuestFPUState
 %endif
         xor     eax, eax
         ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-        o64 fxsave  [pXState]
-
-        ; Restore the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
-        test    dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
-        jnz     short .fpu_load_32_or_64_darwin
-        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
-        fxrstor [pXState]
-        jmp     short .fpu_load_done_darwin
-.fpu_load_32_or_64_darwin:
-        RESTORE_32_OR_64_FPU pCpumCpu, pXState
-.fpu_load_done_darwin:
-
-        jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-        dd      .done, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif
 ENDPROC   cpumR0SaveHostRestoreGuestFPUState
 
 
@@ -337,26 +589,8 @@ BEGINPROC cpumR0SaveHostFPUState
         cli                             ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
         SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
 
-        ;
-        ; Save the host state.
-        ;
-        mov     pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
-        jz      .legacy_mode
-        db      0xea                    ; jmp far .sixtyfourbit_mode
-        dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
-%endif
+        CPUMR0_SAVE_HOST
 
-%ifdef RT_ARCH_AMD64
-        o64 fxsave [pXstate]
-%else
-        fxsave  [pXState]
-%endif
-
-.done:
         RESTORE_CR0 xCX
         or      dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
         popf
@@ -427,35 +661,9 @@ BEGINPROC cpumR0SaveGuestRestoreHostFPUState
         cli                             ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
         SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
 
-        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
-        jz      .legacy_mode
-        db      0xea                    ; jmp far .sixtyfourbit_mode
-        dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
-%endif
-
-%ifdef RT_ARCH_AMD64
-        ; Save the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
-        test    dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
-        jnz     short .fpu_save_32_or_64
-        fxsave  [pXState]
-        jmp     short .fpu_save_done
-.fpu_save_32_or_64:
-        SAVE_32_OR_64_FPU pCpumCpu, pXState
-.fpu_save_done:
+        CPUMR0_SAVE_GUEST
+        CPUMR0_LOAD_HOST
 
-        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
-        o64 fxrstor [pXState]           ; Use explicit REX prefix. See @bugref{6398}.
-%else
-        fxsave  [pXState]               ; ASSUMES that all VT-x/AMD-V boxes support fxsave/fxrstor (safe assumption)
-        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
-        fxrstor [pXState]
-%endif
-
-.done:
         RESTORE_CR0 xCX
         and     dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
         popf
@@ -468,27 +676,6 @@ BEGINPROC cpumR0SaveGuestRestoreHostFPUState
 %endif
         xor     eax, eax
         ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-        ; Save the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
-        test    dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
-        jnz     short .fpu_save_32_or_64_darwin
-        fxsave  [pXState]
-        jmp     short .fpu_save_done_darwin
-.fpu_save_32_or_64_darwin:
-        SAVE_32_OR_64_FPU pCpumCpu, pXState
-.fpu_save_done_darwin:
-
-        mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
-        o64 fxrstor [pXstate]
-        jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-        dd      .done, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif
 %undef pCpumCpu
 %undef pXState
 ENDPROC   cpumR0SaveGuestRestoreHostFPUState
@@ -533,23 +720,8 @@ BEGINPROC cpumR0RestoreHostFPUState
         cli                             ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
         SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
 
-        mov     pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-        cmp     byte [NAME(g_fCPUMIs64bitHost)], 0
-        jz      .legacy_mode
-        db      0xea                    ; jmp far .sixtyfourbit_mode
-        dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
-%endif
-
-%ifdef RT_ARCH_AMD64
-        o64 fxrstor [pXState]
-%else
-        fxrstor [pXState]
-%endif
+        CPUMR0_LOAD_HOST
 
-.done:
         RESTORE_CR0 xCX
         and     dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
         popf
@@ -562,17 +734,6 @@ BEGINPROC cpumR0RestoreHostFPUState
 %endif
         xor     eax, eax
         ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-        o64 fxrstor [pXState]
-        jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-        dd      .done, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif
 %undef pCpumCPu
 %undef pXState
 ENDPROC   cpumR0RestoreHostFPUState
diff --git a/src/VBox/VMM/VMMR0/HMR0.cpp b/src/VBox/VMM/VMMR0/HMR0.cpp
index 6b73d4e..f7988d6 100644
--- a/src/VBox/VMM/VMMR0/HMR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMR0.cpp
@@ -4,7 +4,7 @@
  */
 
 /*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
  * available from http://www.virtualbox.org. This file is free software;
@@ -25,6 +25,7 @@
 #include <VBox/vmm/vm.h>
 #include <VBox/vmm/hm_vmx.h>
 #include <VBox/vmm/hm_svm.h>
+#include <VBox/vmm/gim.h>
 #include <VBox/err.h>
 #include <VBox/log.h>
 #include <iprt/assert.h>
@@ -1210,10 +1211,8 @@ VMMR0_INT_DECL(int) HMR0InitVM(PVM pVM)
     pVM->hm.s.cpuid.u32AMDFeatureECX    = g_HvmR0.cpuid.u32AMDFeatureECX;
     pVM->hm.s.cpuid.u32AMDFeatureEDX    = g_HvmR0.cpuid.u32AMDFeatureEDX;
     pVM->hm.s.lLastError                = g_HvmR0.lLastError;
-
     pVM->hm.s.uMaxAsid                  = g_HvmR0.uMaxAsid;
 
-
     if (!pVM->hm.s.cMaxResumeLoops) /* allow ring-3 overrides */
     {
         pVM->hm.s.cMaxResumeLoops       = 1024;
@@ -1227,8 +1226,9 @@ VMMR0_INT_DECL(int) HMR0InitVM(PVM pVM)
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
         PVMCPU pVCpu = &pVM->aCpus[i];
-        pVCpu->hm.s.idEnteredCpu = NIL_RTCPUID;
-        pVCpu->hm.s.idLastCpu    = NIL_RTCPUID;
+        pVCpu->hm.s.idEnteredCpu   = NIL_RTCPUID;
+        pVCpu->hm.s.idLastCpu      = NIL_RTCPUID;
+        pVCpu->hm.s.fGIMTrapXcptUD = GIMShouldTrapXcptUD(pVCpu);
 
         /* We'll aways increment this the first time (host uses ASID 0). */
         AssertReturn(!pVCpu->hm.s.uCurrentAsid, VERR_HM_IPE_3);
diff --git a/src/VBox/VMM/VMMR0/HMSVMR0.cpp b/src/VBox/VMM/VMMR0/HMSVMR0.cpp
index 8475862..dfd1a7e 100644
--- a/src/VBox/VMM/VMMR0/HMSVMR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMSVMR0.cpp
@@ -669,8 +669,6 @@ VMMR0DECL(int) SVMR0SetupVM(PVM pVM)
     AssertReturn(pVM, VERR_INVALID_PARAMETER);
     Assert(pVM->hm.s.svm.fSupported);
 
-    pVM->hm.s.fTrapXcptUD             = GIMShouldTrapXcptUD(pVM);
-    uint32_t const fGimXcptIntercepts = pVM->hm.s.fTrapXcptUD ? RT_BIT(X86_XCPT_UD) : 0;
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
         PVMCPU   pVCpu = &pVM->aCpus[i];
@@ -787,7 +785,8 @@ VMMR0DECL(int) SVMR0SetupVM(PVM pVM)
 #endif
 
         /* Apply the exceptions intercepts needed by the GIM provider. */
-        pVmcb->ctrl.u32InterceptException |= fGimXcptIntercepts;
+        if (pVCpu->hm.s.fGIMTrapXcptUD)
+            pVmcb->ctrl.u32InterceptException |= RT_BIT(X86_XCPT_UD);
 
         /*
          * The following MSRs are saved/restored automatically during the world-switch.
@@ -1634,6 +1633,30 @@ static int hmR0SvmLoadGuestApicState(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX pCtx
 
 
 /**
+ * Loads the exception interrupts required for guest execution in the VMCB.
+ *
+ * @returns VBox status code.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pVmcb       Pointer to the VM control block.
+ * @param   pCtx        Pointer to the guest-CPU context.
+ */
+static int hmR0SvmLoadGuestXcptIntercepts(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX pCtx)
+{
+    int rc = VINF_SUCCESS;
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
+    {
+        /* The remaining intercepts are handled elsewhere, e.g. in hmR0SvmLoadSharedCR0(). */
+        if (pVCpu->hm.s.fGIMTrapXcptUD)
+            hmR0SvmAddXcptIntercept(pVmcb, X86_XCPT_UD);
+        else
+            hmR0SvmRemoveXcptIntercept(pVmcb, X86_XCPT_UD);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+    }
+    return rc;
+}
+
+
+/**
  * Sets up the appropriate function to run guest code.
  *
  * @returns VBox status code.
@@ -1817,6 +1840,9 @@ static int hmR0SvmLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
     rc = hmR0SvmLoadGuestApicState(pVCpu, pVmcb, pCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0SvmLoadGuestApicState! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
 
+    rc = hmR0SvmLoadGuestXcptIntercepts(pVCpu, pVmcb, pCtx);
+    AssertLogRelMsgRCReturn(rc, ("hmR0SvmLoadGuestXcptIntercepts! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
+
     rc = hmR0SvmSetupVMRunHandler(pVCpu, pCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0SvmSetupVMRunHandler! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
 
@@ -3510,6 +3536,9 @@ DECLINLINE(int) hmR0SvmHandleExit(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSv
         case SVM_EXIT_WRITE_CR8:
             return hmR0SvmExitWriteCRx(pVCpu, pCtx, pSvmTransient);
 
+        case SVM_EXIT_VMMCALL:
+            return hmR0SvmExitVmmCall(pVCpu, pCtx, pSvmTransient);
+
         case SVM_EXIT_VINTR:
             return hmR0SvmExitVIntr(pVCpu, pCtx, pSvmTransient);
 
@@ -3552,9 +3581,6 @@ DECLINLINE(int) hmR0SvmHandleExit(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSv
                 case SVM_EXIT_TASK_SWITCH:
                     return hmR0SvmExitTaskSwitch(pVCpu, pCtx, pSvmTransient);
 
-                case SVM_EXIT_VMMCALL:
-                    return hmR0SvmExitVmmCall(pVCpu, pCtx, pSvmTransient);
-
                 case SVM_EXIT_IRET:
                     return hmR0SvmExitIret(pVCpu, pCtx, pSvmTransient);
 
@@ -3898,7 +3924,7 @@ DECLINLINE(void) hmR0SvmSetPendingXcptDF(PVMCPU pVCpu)
  *
  * @returns VBox status code.
  * @retval VINF_SUCCESS if the access was handled successfully.
- * @retval VERR_NOT_FOUND if no patch record for this eip could be found.
+ * @retval VERR_NOT_FOUND if no patch record for this RIP could be found.
  * @retval VERR_SVM_UNEXPECTED_PATCH_TYPE if the found patch type is invalid.
  *
  * @param   pVM         Pointer to the VM.
@@ -4997,6 +5023,7 @@ HMSVM_EXIT_DECL hmR0SvmExitTaskSwitch(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT
 HMSVM_EXIT_DECL hmR0SvmExitVmmCall(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)
 {
     HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
+    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitVmcall);
 
     /* First check if this is a patched VMMCALL for mov TPR */
     int rc = hmR0SvmEmulateMovTpr(pVCpu->CTX_SUFF(pVM), pVCpu, pCtx);
@@ -5007,14 +5034,13 @@ HMSVM_EXIT_DECL hmR0SvmExitVmmCall(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pS
     }
     else if (rc == VERR_NOT_FOUND)
     {
-        /* Handle GIM provider hypercalls. */
-        if (GIMAreHypercallsEnabled(pVCpu))
+        if (pVCpu->hm.s.fHypercallsEnabled)
         {
             rc = GIMHypercall(pVCpu, pCtx);
-            /* If the hypercall changes anything other than guest general-purpose registers,
-               we would need to reload the guest changed bits on VM-reentry. */
             if (RT_SUCCESS(rc))
             {
+                /* If the hypercall changes anything other than guest general-purpose registers,
+                   we would need to reload the guest changed bits here before VM-reentry. */
                 hmR0SvmUpdateRip(pVCpu, pCtx, 3);
                 return VINF_SUCCESS;
             }
@@ -5226,10 +5252,8 @@ HMSVM_EXIT_DECL hmR0SvmExitXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSv
 
     HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY();
 
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (   pVM->hm.s.fTrapXcptUD
-        && GIMAreHypercallsEnabled(pVCpu))
-        GIMXcptUD(pVCpu, pCtx);
+    if (pVCpu->hm.s.fGIMTrapXcptUD)
+        GIMXcptUD(pVCpu, pCtx, NULL /* pDis */);
     else
         hmR0SvmSetPendingXcptUD(pVCpu);
 
diff --git a/src/VBox/VMM/VMMR0/HMVMXR0.cpp b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
index 361e646..1cc5a96 100644
--- a/src/VBox/VMM/VMMR0/HMVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
@@ -492,7 +492,12 @@ static const PFNVMXEXITHANDLER g_apfnVMExitHandlers[VMX_EXIT_MAX + 1] =
  /* 56  UNDEFINED                        */  hmR0VmxExitErrUndefined,
  /* 57  VMX_EXIT_RDRAND                  */  hmR0VmxExitRdrand,
  /* 58  VMX_EXIT_INVPCID                 */  hmR0VmxExitInvpcid,
- /* 59  VMX_EXIT_VMFUNC                  */  hmR0VmxExitSetPendingXcptUD
+ /* 59  VMX_EXIT_VMFUNC                  */  hmR0VmxExitSetPendingXcptUD,
+ /* 60  VMX_EXIT_RESERVED_60             */  hmR0VmxExitErrUndefined,
+ /* 61  VMX_EXIT_RDSEED                  */  hmR0VmxExitErrUndefined, /* only spurious exits, so undefined */
+ /* 62  VMX_EXIT_RESERVED_62             */  hmR0VmxExitErrUndefined,
+ /* 63  VMX_EXIT_XSAVES                  */  hmR0VmxExitSetPendingXcptUD,
+ /* 64  VMX_EXIT_XRSTORS                 */  hmR0VmxExitSetPendingXcptUD,
 };
 #endif /* HMVMX_USE_FUNCTION_TABLE */
 
@@ -2634,7 +2639,7 @@ static int hmR0VmxInitXcptBitmap(PVM pVM, PVMCPU pVCpu)
 
     LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu));
 
-    uint32_t u32XcptBitmap = 0;
+    uint32_t u32XcptBitmap = pVCpu->hm.s.fGIMTrapXcptUD ? RT_BIT(X86_XCPT_UD) : 0;
 
     /* Without Nested Paging, #PF must cause a VM-exit so we can sync our shadow page tables. */
     if (!pVM->hm.s.fNestedPaging)
@@ -3553,6 +3558,42 @@ static int hmR0VmxLoadGuestIntrState(PVMCPU pVCpu, uint32_t uIntrState)
 
 
 /**
+ * Loads the exception intercepts required for guest execution in the VMCS.
+ *
+ * @returns VBox status code.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pMixedCtx   Pointer to the guest-CPU context. The data may be
+ *                      out-of-sync. Make sure to update the required fields
+ *                      before using them.
+ */
+static int hmR0VmxLoadGuestXcptIntercepts(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
+{
+    NOREF(pMixedCtx);
+    int rc = VINF_SUCCESS;
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
+    {
+        /* The remaining exception intercepts are handled elsewhere, e.g. in hmR0VmxLoadSharedCR0(). */
+        if (pVCpu->hm.s.fGIMTrapXcptUD)
+            pVCpu->hm.s.vmx.u32XcptBitmap |= RT_BIT(X86_XCPT_UD);
+        else
+        {
+#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
+            pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_UD);
+#endif
+        }
+
+        rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
+        AssertRCReturn(rc, rc);
+
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+        Log4(("Load[%RU32]: VMX_VMCS32_CTRL_EXCEPTION_BITMAP=%#RX64 fContextUseFlags=%#RX32\n", pVCpu->idCpu,
+              pVCpu->hm.s.vmx.u32XcptBitmap, HMCPU_CF_VALUE(pVCpu)));
+    }
+    return rc;
+}
+
+
+/**
  * Loads the guest's RIP into the guest-state area in the VMCS.
  *
  * @returns VBox status code.
@@ -3778,6 +3819,7 @@ static int hmR0VmxLoadSharedCR0(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
             /* For now, cleared here as mode-switches can happen outside HM/VT-x. See @bugref{7626} comment #11. */
             pVCpu->hm.s.vmx.u32XcptBitmap &= ~HMVMX_REAL_MODE_XCPT_MASK;
         }
+        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
 
         if (fInterceptNM)
             pVCpu->hm.s.vmx.u32XcptBitmap |= RT_BIT(X86_XCPT_NM);
@@ -3822,11 +3864,9 @@ static int hmR0VmxLoadSharedCR0(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
         u32GuestCR0 &= uZapCR0;
         u32GuestCR0 &= ~(X86_CR0_CD | X86_CR0_NW);          /* Always enable caching. */
 
-        /* Write VT-x's view of the guest CR0 into the VMCS and update the exception bitmap. */
+        /* Write VT-x's view of the guest CR0 into the VMCS. */
         rc = VMXWriteVmcs32(VMX_VMCS_GUEST_CR0, u32GuestCR0);
         AssertRCReturn(rc, rc);
-        rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
-        AssertRCReturn(rc, rc);
         Log4(("Load[%RU32]: VMX_VMCS_GUEST_CR0=%#RX32 (uSetCR0=%#RX32 uZapCR0=%#RX32)\n", pVCpu->idCpu, u32GuestCR0, uSetCR0,
               uZapCR0));
 
@@ -4219,15 +4259,17 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
      */
     if (   fInterceptDB
         || pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
+    {
         pVCpu->hm.s.vmx.u32XcptBitmap |= RT_BIT(X86_XCPT_DB);
+        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+    }
     else
     {
 #ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
         pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_DB);
+        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
 #endif
     }
-    rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
-    AssertRCReturn(rc, rc);
 
     /*
      * Update the processor-based VM-execution controls regarding intercepting MOV DRx instructions.
@@ -6716,6 +6758,28 @@ static int hmR0VmxSaveGuestState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
 
 
 /**
+ * Ensures that we've got a complete basic context.
+ *
+ * This excludes the FPU, SSE, AVX, and similar extended state.  The interface
+ * is for the interpreter.
+ *
+ * @returns VBox status code.
+ * @param   pVCpu           Pointer to the VMCPU of the calling EMT.
+ * @param   pMixedCtx       Pointer to the guest-CPU context which may have data
+ *                          needing to be synced in.
+ * @thread  EMT(pVCpu)
+ */
+VMMR0_INT_DECL(int) HMR0EnsureCompleteBasicContext(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
+{
+    /* Note! Since this is only applicable to VT-x, the implementation is placed
+             in the VT-x part of the sources instead of the generic stuff. */
+    if (pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fSupported)
+        return hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
+    return VINF_SUCCESS;
+}
+
+
+/**
  * Check per-VM and per-VCPU force flag actions that require us to go back to
  * ring-3 for one reason or another.
  *
@@ -8294,6 +8358,9 @@ static int hmR0VmxLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     rc = hmR0VmxLoadGuestApicState(pVCpu, pMixedCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxLoadGuestApicState! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
 
+    rc = hmR0VmxLoadGuestXcptIntercepts(pVCpu, pMixedCtx);
+    AssertLogRelMsgRCReturn(rc, ("hmR0VmxLoadGuestXcptIntercepts! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
+
     /*
      * Loading Rflags here is fine, even though Rflags.TF might depend on guest debug state (which is not loaded here).
      * It is re-evaluated and updated if necessary in hmR0VmxLoadSharedState().
@@ -8355,6 +8422,14 @@ static void hmR0VmxLoadSharedState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
         HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_LAZY_MSRS);
     }
 
+    /* Loading CR0, debug state might have changed intercepts, update VMCS. */
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
+    {
+        int rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
+        AssertRC(rc);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+    }
+
     AssertMsg(!HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_HOST_GUEST_SHARED_STATE),
               ("fContextUseFlags=%#RX32\n", HMCPU_CF_VALUE(pVCpu)));
 }
@@ -9088,8 +9163,13 @@ DECLINLINE(int) hmR0VmxHandleExit(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIEN
         case VMX_EXIT_INVEPT:
         case VMX_EXIT_INVVPID:
         case VMX_EXIT_VMFUNC:
+        case VMX_EXIT_XSAVES:
+        case VMX_EXIT_XRSTORS:
             rc = hmR0VmxExitSetPendingXcptUD(pVCpu, pMixedCtx, pVmxTransient);
             break;
+        case VMX_EXIT_RESERVED_60:
+        case VMX_EXIT_RDSEED: /* only spurious exits, so undefined */
+        case VMX_EXIT_RESERVED_62:
         default:
             rc = hmR0VmxExitErrUndefined(pVCpu, pMixedCtx, pVmxTransient);
             break;
@@ -10240,32 +10320,32 @@ HMVMX_EXIT_DECL hmR0VmxExitRdpmc(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT
 HMVMX_EXIT_DECL hmR0VmxExitVmcall(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
 {
     HMVMX_VALIDATE_EXIT_HANDLER_PARAMS();
+    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitVmcall);
 
-    int rc = VERR_NOT_SUPPORTED;
-    if (GIMAreHypercallsEnabled(pVCpu))
+    if (pVCpu->hm.s.fHypercallsEnabled)
     {
-        rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
+#if 0
+        int rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
+        AssertRCReturn(rc, rc);
+#else
+        /* Aggressive state sync. for now. */
+        int rc  = hmR0VmxSaveGuestRip(pVCpu, pMixedCtx);
+        rc     |= hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx);    /* For long-mode checks in gimKvmHypercall(). */
+#endif
         AssertRCReturn(rc, rc);
 
         rc = GIMHypercall(pVCpu, pMixedCtx);
+        if (RT_SUCCESS(rc))
+        {
+            /* If the hypercall changes anything other than guest general-purpose registers,
+               we would need to reload the guest changed bits here before VM-reentry. */
+            hmR0VmxAdvanceGuestRip(pVCpu, pMixedCtx, pVmxTransient);
+            return VINF_SUCCESS;
+        }
     }
 
-    if (RT_SUCCESS(rc))
-    {
-        rc = hmR0VmxAdvanceGuestRip(pVCpu, pMixedCtx, pVmxTransient);
-        Assert(pVmxTransient->cbInstr == 3);
-
-        /* If the hypercall changes anything other than guest general-purpose registers,
-           we would need to reload the guest changed bits on VM-reentry. */
-    }
-    else
-    {
-        hmR0VmxSetPendingXcptUD(pVCpu, pMixedCtx);
-        rc = VINF_SUCCESS;
-    }
-
-    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitVmcall);
-    return rc;
+    hmR0VmxSetPendingXcptUD(pVCpu, pMixedCtx);
+    return VINF_SUCCESS;
 }
 
 
@@ -10512,7 +10592,7 @@ HMVMX_EXIT_DECL hmR0VmxExitXsetbv(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIEN
 {
     HMVMX_VALIDATE_EXIT_HANDLER_PARAMS();
 
-    /* We expose XSETBV to the guest, fallback to the recompiler for emulation. */
+    /* We expose XSETBV to the guest, fallback to the interpreter for emulation. */
     /** @todo check if XSETBV is supported by the recompiler. */
     return VERR_EM_INTERPRETER;
 }
@@ -10525,7 +10605,7 @@ HMVMX_EXIT_DECL hmR0VmxExitInvpcid(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIE
 {
     HMVMX_VALIDATE_EXIT_HANDLER_PARAMS();
 
-    /* The guest should not invalidate the host CPU's TLBs, fallback to recompiler. */
+    /* The guest should not invalidate the host CPU's TLBs, fallback to interpreter. */
     /** @todo implement EMInterpretInvpcid() */
     return VERR_EM_INTERPRETER;
 }
@@ -10872,42 +10952,39 @@ HMVMX_EXIT_DECL hmR0VmxExitTprBelowThreshold(PVMCPU pVCpu, PCPUMCTX pMixedCtx, P
  * @retval VINF_PGM_CHANGE_MODE when shadow paging mode changed, back to ring-3.
  * @retval VINF_PGM_SYNC_CR3 CR3 sync is required, back to ring-3.
  * @retval VERR_EM_INTERPRETER when something unexpected happened, fallback to
- *         recompiler.
+ *         interpreter.
  */
 HMVMX_EXIT_DECL hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
 {
     HMVMX_VALIDATE_EXIT_HANDLER_PARAMS();
     STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatExitMovCRx, y2);
     int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
+    rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
     AssertRCReturn(rc, rc);
 
     RTGCUINTPTR const uExitQualification = pVmxTransient->uExitQualification;
     uint32_t const uAccessType           = VMX_EXIT_QUALIFICATION_CRX_ACCESS(uExitQualification);
     PVM pVM                              = pVCpu->CTX_SUFF(pVM);
+    VBOXSTRICTRC rcStrict;
+    rc  = hmR0VmxSaveGuestRipRspRflags(pVCpu, pMixedCtx);
+    rc |= hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx); /* Only really need CS+SS. */
     switch (uAccessType)
     {
         case VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE:       /* MOV to CRx */
         {
-#if 0
-            /* EMInterpretCRxWrite() references a lot of guest state (EFER, RFLAGS, Segment Registers, etc.) Sync entire state */
-            rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
-#else
-            rc  = hmR0VmxSaveGuestRipRspRflags(pVCpu, pMixedCtx);
             rc |= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);
-            rc |= hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx);
-#endif
             AssertRCReturn(rc, rc);
 
-            rc = EMInterpretCRxWrite(pVM, pVCpu, CPUMCTX2CORE(pMixedCtx),
-                                     VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification),
-                                     VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification));
-            Assert(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_PGM_SYNC_CR3);
-
+            rcStrict = IEMExecDecodedMovCRxWrite(pVCpu, pVmxTransient->cbInstr,
+                                                 VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification),
+                                                 VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification));
+            AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT || rcStrict == VINF_PGM_CHANGE_MODE
+                      || rcStrict == VINF_PGM_SYNC_CR3, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
             switch (VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification))
             {
                 case 0: /* CR0 */
                     HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR0);
-                    Log4(("CRX CR0 write rc=%d CR0=%#RX64\n", rc, pMixedCtx->cr0));
+                    Log4(("CRX CR0 write rcStrict=%Rrc CR0=%#RX64\n", VBOXSTRICTRC_VAL(rcStrict), pMixedCtx->cr0));
                     break;
                 case 2: /* CR2 */
                     /* Nothing to do here, CR2 it's not part of the VMCS. */
@@ -10915,15 +10992,15 @@ HMVMX_EXIT_DECL hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIEN
                 case 3: /* CR3 */
                     Assert(!pVM->hm.s.fNestedPaging || !CPUMIsGuestPagingEnabledEx(pMixedCtx));
                     HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR3);
-                    Log4(("CRX CR3 write rc=%d CR3=%#RX64\n", rc, pMixedCtx->cr3));
+                    Log4(("CRX CR3 write rcStrict=%Rrc CR3=%#RX64\n", VBOXSTRICTRC_VAL(rcStrict), pMixedCtx->cr3));
                     break;
                 case 4: /* CR4 */
                     HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR4);
-                    Log4(("CRX CR4 write rc=%d CR4=%#RX64\n", rc, pMixedCtx->cr4));
+                    Log4(("CRX CR4 write rc=%Rrc CR4=%#RX64\n", VBOXSTRICTRC_VAL(rcStrict), pMixedCtx->cr4));
                     break;
                 case 8: /* CR8 */
                     Assert(!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW));
-                    /* CR8 contains the APIC TPR. Was updated by EMInterpretCRxWrite(). */
+                    /* CR8 contains the APIC TPR. Was updated by IEMExecDecodedMovCRxWrite(). */
                     HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE);
                     break;
                 default:
@@ -10937,10 +11014,9 @@ HMVMX_EXIT_DECL hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIEN
 
         case VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ:        /* MOV from CRx */
         {
-            /* EMInterpretCRxRead() requires EFER MSR, CS. */
-            rc  = hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx);
             rc |= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);
             AssertRCReturn(rc, rc);
+
             Assert(   !pVM->hm.s.fNestedPaging
                    || !CPUMIsGuestPagingEnabledEx(pMixedCtx)
                    || VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification) != 3);
@@ -10949,57 +11025,48 @@ HMVMX_EXIT_DECL hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIEN
             Assert(   VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification) != 8
                    || !(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW));
 
-            rc = EMInterpretCRxRead(pVM, pVCpu, CPUMCTX2CORE(pMixedCtx),
-                                    VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification),
-                                    VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification));
-            Assert(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER);
+            rcStrict = IEMExecDecodedMovCRxRead(pVCpu, pVmxTransient->cbInstr,
+                                                VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification),
+                                                VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification));
+            AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxRead[VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification)]);
-            Log4(("CRX CR%d Read access rc=%d\n", VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification), rc));
+            Log4(("CRX CR%d Read access rcStrict=%Rrc\n", VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification),
+                  VBOXSTRICTRC_VAL(rcStrict)));
             break;
         }
 
         case VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS:        /* CLTS (Clear Task-Switch Flag in CR0) */
         {
-            rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
-            AssertRCReturn(rc, rc);
-            rc = EMInterpretCLTS(pVM, pVCpu);
+            rc |= hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
             AssertRCReturn(rc, rc);
+            rcStrict = IEMExecDecodedClts(pVCpu, pVmxTransient->cbInstr);
+            AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
             HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR0);
             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitClts);
-            Log4(("CRX CLTS write rc=%d\n", rc));
+            Log4(("CRX CLTS rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict)));
             break;
         }
 
         case VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW:        /* LMSW (Load Machine-Status Word into CR0) */
         {
-            rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
+            rc |= hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
             AssertRCReturn(rc, rc);
-            rc = EMInterpretLMSW(pVM, pVCpu, CPUMCTX2CORE(pMixedCtx), VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(uExitQualification));
-            if (RT_LIKELY(rc == VINF_SUCCESS))
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR0);
+            rcStrict = IEMExecDecodedLmsw(pVCpu, pVmxTransient->cbInstr,
+                                          VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(uExitQualification));
+            AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT || rcStrict == VINF_PGM_CHANGE_MODE, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitLmsw);
-            Log4(("CRX LMSW write rc=%d\n", rc));
+            Log4(("CRX LMSW rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict)));
             break;
         }
 
         default:
-        {
-            AssertMsgFailed(("Invalid access-type in Mov CRx VM-exit qualification %#x\n", uAccessType));
-            rc = VERR_VMX_UNEXPECTED_EXCEPTION;
-        }
-    }
-
-    /* Validate possible error codes. */
-    Assert(rc == VINF_SUCCESS || rc == VINF_PGM_CHANGE_MODE || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_SYNC_CR3
-           || rc == VERR_VMX_UNEXPECTED_EXCEPTION);
-    if (RT_SUCCESS(rc))
-    {
-        int rc2 = hmR0VmxAdvanceGuestRip(pVCpu, pMixedCtx, pVmxTransient);
-        AssertRCReturn(rc2, rc2);
+            AssertMsgFailedReturn(("Invalid access-type in Mov CRx VM-exit qualification %#x\n", uAccessType),
+                                  VERR_VMX_UNEXPECTED_EXCEPTION);
     }
 
+    HMCPU_CF_SET(pVCpu, rcStrict != VINF_IEM_RAISED_XCPT ? HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS : HM_CHANGED_ALL_GUEST);
     STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitMovCRx, y2);
-    return rc;
+    return VBOXSTRICTRC_TODO(rcStrict);
 }
 
 
@@ -11403,8 +11470,7 @@ HMVMX_EXIT_DECL hmR0VmxExitMovDRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIEN
         {
 #ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
             pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_DB);
-            rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
-            AssertRCReturn(rc, rc);
+            HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
 #endif
         }
 
diff --git a/src/VBox/VMM/VMMR3/CPUM.cpp b/src/VBox/VMM/VMMR3/CPUM.cpp
index 48d971b..52fedf7 100644
--- a/src/VBox/VMM/VMMR3/CPUM.cpp
+++ b/src/VBox/VMM/VMMR3/CPUM.cpp
@@ -646,7 +646,24 @@ VMMR3DECL(int) CPUMR3Init(PVM pVM)
     pVM->cpum.s.CR4.OrMask  = X86_CR4_OSFXSR;
 
     /*
-     * Allocate memory for the extended CPU state.
+     * Figure out which XSAVE/XRSTOR features are available on the host.
+     */
+    uint64_t fXStateHostMask = 0;
+    if (   pVM->cpum.s.HostFeatures.fXSaveRstor
+        && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor)
+    {
+        fXStateHostMask = ASMGetXcr0() & (  XSAVE_C_X87 | XSAVE_C_SSE | XSAVE_C_YMM | XSAVE_C_OPMASK
+                                          | XSAVE_C_ZMM_HI256 | XSAVE_C_ZMM_16HI);
+        AssertLogRelMsgStmt((fXStateHostMask & (XSAVE_C_X87 | XSAVE_C_SSE)) == (XSAVE_C_X87 | XSAVE_C_SSE),
+                            ("%#llx\n", fXStateHostMask), fXStateHostMask = 0);
+    }
+    pVM->cpum.s.fXStateHostMask = fXStateHostMask;
+    if (!HMIsEnabled(pVM)) /* For raw-mode, we only use XSAVE/XRSTOR when the guest starts using it (CPUID/CR4 visibility). */
+        fXStateHostMask = 0;
+    LogRel(("CPUM: fXStateHostMask=%#llx; initial: %#llx\n", pVM->cpum.s.fXStateHostMask, fXStateHostMask));
+
+    /*
+     * Allocate memory for the extended CPU state and initialize the host XSAVE/XRSTOR mask.
      */
     uint32_t cbMaxXState = pVM->cpum.s.HostFeatures.cbMaxExtendedState;
     cbMaxXState = RT_ALIGN(cbMaxXState, 128);
@@ -675,6 +692,8 @@ VMMR3DECL(int) CPUMR3Init(PVM pVM)
         pVCpu->cpum.s.Hyper.pXStateR0 = MMHyperR3ToR0(pVM, pbXStates);
         pVCpu->cpum.s.Hyper.pXStateRC = MMHyperR3ToR0(pVM, pbXStates);
         pbXStates += cbMaxXState;
+
+        pVCpu->cpum.s.Host.fXStateMask = fXStateHostMask;
     }
 
     /*
@@ -897,6 +916,13 @@ VMMR3DECL(void) CPUMR3ResetCpu(PVM pVM, PVMCPU pVCpu)
     pFpuCtx->MXCSR                  = 0x1F80;
     pFpuCtx->MXCSR_MASK             = 0xffff; /** @todo REM always changed this for us. Should probably check if the HW really
                                                         supports all bits, since a zero value here should be read as 0xffbf. */
+    pCtx->aXcr[0]                   = XSAVE_C_X87;
+    if (pVM->cpum.s.HostFeatures.cbMaxExtendedState >= RT_OFFSETOF(X86XSAVEAREA, Hdr))
+    {
+        /* The entire FXSAVE state needs loading when we switch to XSAVE/XRSTOR
+           as we don't know what happened before.  (Bother optimize later?) */
+        pCtx->pXStateR3->Hdr.bmXState = XSAVE_C_X87 | XSAVE_C_SSE;
+    }
 
     /*
      * MSRs.
diff --git a/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp b/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
index a1da4bd..ef2036f 100644
--- a/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
+++ b/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
@@ -1508,7 +1508,7 @@ static PCCPUMCPUIDLEAF cpumR3CpuIdFindLeafEx(PCCPUMCPUIDLEAF paLeaves, uint32_t
         return pLeaf;
 
     /* Linear sub-leaf search. Lazy as usual. */
-    cLeaves = pLeaf - paLeaves;
+    cLeaves -= pLeaf - paLeaves;
     while (   cLeaves-- > 0
            && pLeaf->uLeaf == uLeaf)
     {
@@ -1528,14 +1528,18 @@ int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUM
     {
         AssertLogRelReturn(paLeaves[0].uLeaf == 0, VERR_CPUM_IPE_1);
         AssertLogRelReturn(paLeaves[1].uLeaf == 1, VERR_CPUM_IPE_1);
-
-        pFeatures->enmCpuVendor = CPUMR3CpuIdDetectVendorEx(paLeaves[0].uEax,
-                                                            paLeaves[0].uEbx,
-                                                            paLeaves[0].uEcx,
-                                                            paLeaves[0].uEdx);
-        pFeatures->uFamily      = ASMGetCpuFamily(paLeaves[1].uEax);
-        pFeatures->uModel       = ASMGetCpuModel(paLeaves[1].uEax, pFeatures->enmCpuVendor == CPUMCPUVENDOR_INTEL);
-        pFeatures->uStepping    = ASMGetCpuStepping(paLeaves[1].uEax);
+        PCCPUMCPUIDLEAF const pStd0Leaf = cpumR3CpuIdFindLeafEx(paLeaves, cLeaves, 0, 0);
+        AssertLogRelReturn(pStd0Leaf, VERR_CPUM_IPE_1);
+        PCCPUMCPUIDLEAF const pStd1Leaf = cpumR3CpuIdFindLeafEx(paLeaves, cLeaves, 1, 0);
+        AssertLogRelReturn(pStd1Leaf, VERR_CPUM_IPE_1);
+
+        pFeatures->enmCpuVendor = CPUMR3CpuIdDetectVendorEx(pStd0Leaf->uEax,
+                                                            pStd0Leaf->uEbx,
+                                                            pStd0Leaf->uEcx,
+                                                            pStd0Leaf->uEdx);
+        pFeatures->uFamily      = ASMGetCpuFamily(pStd1Leaf->uEax);
+        pFeatures->uModel       = ASMGetCpuModel(pStd1Leaf->uEax, pFeatures->enmCpuVendor == CPUMCPUVENDOR_INTEL);
+        pFeatures->uStepping    = ASMGetCpuStepping(pStd1Leaf->uEax);
         pFeatures->enmMicroarch = CPUMR3CpuIdDetermineMicroarchEx((CPUMCPUVENDOR)pFeatures->enmCpuVendor,
                                                                   pFeatures->uFamily,
                                                                   pFeatures->uModel,
@@ -1544,33 +1548,34 @@ int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUM
         PCCPUMCPUIDLEAF pLeaf = cpumR3CpuIdFindLeaf(paLeaves, cLeaves, 0x80000008);
         if (pLeaf)
             pFeatures->cMaxPhysAddrWidth = pLeaf->uEax & 0xff;
-        else if (paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_PSE36)
+        else if (pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_PSE36)
             pFeatures->cMaxPhysAddrWidth = 36;
         else
             pFeatures->cMaxPhysAddrWidth = 32;
 
         /* Standard features. */
-        pFeatures->fMsr                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_MSR);
-        pFeatures->fApic                = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_APIC);
-        pFeatures->fX2Apic              = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_X2APIC);
-        pFeatures->fPse                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_PSE);
-        pFeatures->fPse36               = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_PSE36);
-        pFeatures->fPae                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_PAE);
-        pFeatures->fPat                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_PAT);
-        pFeatures->fFxSaveRstor         = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_FXSR);
-        pFeatures->fXSaveRstor          = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_XSAVE);
-        pFeatures->fMmx                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_MMX);
-        pFeatures->fSse                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_SSE);
-        pFeatures->fSse2                = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_SSE2);
-        pFeatures->fSse3                = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSE3);
-        pFeatures->fSsse3               = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSSE3);
-        pFeatures->fSse41               = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSE4_1);
-        pFeatures->fSse42               = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSE4_2);
-        pFeatures->fAvx                 = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_AVX);
-        pFeatures->fTsc                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_TSC);
-        pFeatures->fSysEnter            = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_SEP);
-        pFeatures->fHypervisorPresent   = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_HVP);
-        pFeatures->fMonitorMWait        = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_MONITOR);
+        pFeatures->fMsr                 = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_MSR);
+        pFeatures->fApic                = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_APIC);
+        pFeatures->fX2Apic              = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_X2APIC);
+        pFeatures->fPse                 = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_PSE);
+        pFeatures->fPse36               = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_PSE36);
+        pFeatures->fPae                 = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_PAE);
+        pFeatures->fPat                 = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_PAT);
+        pFeatures->fFxSaveRstor         = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_FXSR);
+        pFeatures->fXSaveRstor          = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_XSAVE);
+        pFeatures->fOpSysXSaveRstor     = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_OSXSAVE);
+        pFeatures->fMmx                 = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_MMX);
+        pFeatures->fSse                 = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_SSE);
+        pFeatures->fSse2                = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_SSE2);
+        pFeatures->fSse3                = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_SSE3);
+        pFeatures->fSsse3               = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_SSSE3);
+        pFeatures->fSse41               = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_SSE4_1);
+        pFeatures->fSse42               = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_SSE4_2);
+        pFeatures->fAvx                 = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_AVX);
+        pFeatures->fTsc                 = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_TSC);
+        pFeatures->fSysEnter            = RT_BOOL(pStd1Leaf->uEdx & X86_CPUID_FEATURE_EDX_SEP);
+        pFeatures->fHypervisorPresent   = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_HVP);
+        pFeatures->fMonitorMWait        = RT_BOOL(pStd1Leaf->uEcx & X86_CPUID_FEATURE_ECX_MONITOR);
 
         /* Structured extended features. */
         PCCPUMCPUIDLEAF const pSxfLeaf0 = cpumR3CpuIdFindLeafEx(paLeaves, cLeaves, 7, 0);
@@ -1597,6 +1602,11 @@ int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUM
             pFeatures->fNoExecute       = RT_BOOL(pExtLeaf->uEdx & X86_CPUID_EXT_FEATURE_EDX_NX);
             pFeatures->fLahfSahf        = RT_BOOL(pExtLeaf->uEcx & X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF);
             pFeatures->fRdTscP          = RT_BOOL(pExtLeaf->uEdx & X86_CPUID_EXT_FEATURE_EDX_RDTSCP);
+            pFeatures->fMovCr8In32Bit   = RT_BOOL(pExtLeaf->uEcx & X86_CPUID_AMD_FEATURE_ECX_CMPL);
+            pFeatures->f3DNow           = RT_BOOL(pExtLeaf->uEdx & X86_CPUID_AMD_FEATURE_EDX_3DNOW);
+            pFeatures->f3DNowPrefetch   = (pExtLeaf->uEcx & X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF)
+                                       || (pExtLeaf->uEdx & (  X86_CPUID_EXT_FEATURE_EDX_LONG_MODE
+                                                             | X86_CPUID_AMD_FEATURE_EDX_3DNOW));
         }
 
         if (   pExtLeaf
@@ -1612,6 +1622,7 @@ int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUM
             pFeatures->fFxSaveRstor    |= RT_BOOL(pExtLeaf->uEdx & X86_CPUID_AMD_FEATURE_EDX_FXSR);
             pFeatures->fMmx            |= RT_BOOL(pExtLeaf->uEdx & X86_CPUID_AMD_FEATURE_EDX_MMX);
             pFeatures->fTsc            |= RT_BOOL(pExtLeaf->uEdx & X86_CPUID_AMD_FEATURE_EDX_TSC);
+            pFeatures->fAmdMmxExts      = RT_BOOL(pExtLeaf->uEdx & X86_CPUID_AMD_FEATURE_EDX_AXMMX);
         }
 
         /*
@@ -2100,6 +2111,9 @@ typedef struct CPUMCPUIDCONFIG
     CPUMISAEXTCFG   enmMWaitExtensions;
     CPUMISAEXTCFG   enmSse41;
     CPUMISAEXTCFG   enmSse42;
+    CPUMISAEXTCFG   enmAvx;
+    CPUMISAEXTCFG   enmAvx2;
+    CPUMISAEXTCFG   enmXSave;
     CPUMISAEXTCFG   enmAesNi;
     CPUMISAEXTCFG   enmPClMul;
     CPUMISAEXTCFG   enmPopCnt;
@@ -2435,9 +2449,9 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
                            | (pConfig->enmPopCnt ? X86_CPUID_FEATURE_ECX_POPCNT : 0)
                            //| X86_CPUID_FEATURE_ECX_TSCDEADL - not implemented yet.
                            | (pConfig->enmAesNi ? X86_CPUID_FEATURE_ECX_AES : 0)
-                           //| X86_CPUID_FEATURE_ECX_XSAVE - not implemented yet.
-                           //| X86_CPUID_FEATURE_ECX_OSXSAVE - mirrors CR4.OSXSAVE state
-                           //| X86_CPUID_FEATURE_ECX_AVX   - not implemented yet.
+                           | (pConfig->enmXSave ? X86_CPUID_FEATURE_ECX_XSAVE : 0 )
+                           //| X86_CPUID_FEATURE_ECX_OSXSAVE - mirrors CR4.OSXSAVE state, set dynamically.
+                           | (pConfig->enmAvx ? X86_CPUID_FEATURE_ECX_AVX : 0)
                            //| X86_CPUID_FEATURE_ECX_F16C  - not implemented yet.
                            | (pConfig->enmRdRand ? X86_CPUID_FEATURE_ECX_RDRAND : 0)
                            //| X86_CPUID_FEATURE_ECX_HVP   - Set explicitly later.
@@ -2454,8 +2468,8 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
         PORTABLE_DISABLE_FEATURE_BIT_CFG(1, pStdFeatureLeaf->uEcx, PCLMUL, X86_CPUID_FEATURE_ECX_PCLMUL, pConfig->enmPClMul);
         PORTABLE_DISABLE_FEATURE_BIT_CFG(1, pStdFeatureLeaf->uEcx, POPCNT, X86_CPUID_FEATURE_ECX_POPCNT, pConfig->enmPopCnt);
         PORTABLE_DISABLE_FEATURE_BIT(    1, pStdFeatureLeaf->uEcx, F16C,   X86_CPUID_FEATURE_ECX_F16C);
-        PORTABLE_DISABLE_FEATURE_BIT(    1, pStdFeatureLeaf->uEcx, XSAVE,  X86_CPUID_FEATURE_ECX_XSAVE);
-        PORTABLE_DISABLE_FEATURE_BIT(    1, pStdFeatureLeaf->uEcx, AVX,    X86_CPUID_FEATURE_ECX_AVX);
+        PORTABLE_DISABLE_FEATURE_BIT_CFG(1, pStdFeatureLeaf->uEcx, XSAVE,  X86_CPUID_FEATURE_ECX_XSAVE,  pConfig->enmXSave);
+        PORTABLE_DISABLE_FEATURE_BIT_CFG(1, pStdFeatureLeaf->uEcx, AVX,    X86_CPUID_FEATURE_ECX_AVX,    pConfig->enmAvx);
         PORTABLE_DISABLE_FEATURE_BIT_CFG(1, pStdFeatureLeaf->uEcx, RDRAND, X86_CPUID_FEATURE_ECX_RDRAND, pConfig->enmRdRand);
         PORTABLE_DISABLE_FEATURE_BIT_CFG(1, pStdFeatureLeaf->uEcx, CX16,   X86_CPUID_FEATURE_ECX_CX16,   pConfig->enmCmpXchg16b);
         PORTABLE_DISABLE_FEATURE_BIT(    2, pStdFeatureLeaf->uEcx, SSE3,   X86_CPUID_FEATURE_ECX_SSE3);
@@ -2483,9 +2497,7 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
                                           | X86_CPUID_FEATURE_ECX_TPRUPDATE
                                           | X86_CPUID_FEATURE_ECX_PDCM
                                           | X86_CPUID_FEATURE_ECX_DCA
-                                          | X86_CPUID_FEATURE_ECX_XSAVE
                                           | X86_CPUID_FEATURE_ECX_OSXSAVE
-                                          | X86_CPUID_FEATURE_ECX_AVX
                                           )));
     }
 
@@ -2518,6 +2530,10 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
         pStdFeatureLeaf->uEcx |= X86_CPUID_FEATURE_ECX_POPCNT;
     if (pConfig->enmAesNi == CPUMISAEXTCFG_ENABLED_ALWAYS)
         pStdFeatureLeaf->uEcx |= X86_CPUID_FEATURE_ECX_AES;
+    if (pConfig->enmXSave == CPUMISAEXTCFG_ENABLED_ALWAYS)
+        pStdFeatureLeaf->uEcx |= X86_CPUID_FEATURE_ECX_XSAVE;
+    if (pConfig->enmAvx == CPUMISAEXTCFG_ENABLED_ALWAYS)
+        pStdFeatureLeaf->uEcx |= X86_CPUID_FEATURE_ECX_AVX;
     if (pConfig->enmRdRand == CPUMISAEXTCFG_ENABLED_ALWAYS)
         pStdFeatureLeaf->uEcx |= X86_CPUID_FEATURE_ECX_RDRAND;
 
@@ -2812,7 +2828,7 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
                                //| RT_BIT(2) - reserved
                                //| X86_CPUID_STEXT_FEATURE_EBX_BMI1              RT_BIT(3)
                                //| X86_CPUID_STEXT_FEATURE_EBX_HLE               RT_BIT(4)
-                               //| X86_CPUID_STEXT_FEATURE_EBX_AVX2              RT_BIT(5)
+                               | (pConfig->enmAvx2 ? X86_CPUID_STEXT_FEATURE_EBX_AVX2 : 0)
                                //| RT_BIT(6) - reserved
                                //| X86_CPUID_STEXT_FEATURE_EBX_SMEP              RT_BIT(7)
                                //| X86_CPUID_STEXT_FEATURE_EBX_BMI2              RT_BIT(8)
@@ -2848,7 +2864,7 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
                 if (pCpum->u8PortableCpuIdLevel > 0)
                 {
                     PORTABLE_DISABLE_FEATURE_BIT(    1, pCurLeaf->uEbx, FSGSBASE,   X86_CPUID_STEXT_FEATURE_EBX_FSGSBASE);
-                    PORTABLE_DISABLE_FEATURE_BIT(    1, pCurLeaf->uEbx, AVX2,       X86_CPUID_STEXT_FEATURE_EBX_AVX2);
+                    PORTABLE_DISABLE_FEATURE_BIT_CFG(1, pCurLeaf->uEbx, AVX2,       X86_CPUID_STEXT_FEATURE_EBX_AVX2, pConfig->enmAvx2);
                     PORTABLE_DISABLE_FEATURE_BIT(    1, pCurLeaf->uEbx, SMEP,       X86_CPUID_STEXT_FEATURE_EBX_SMEP);
                     PORTABLE_DISABLE_FEATURE_BIT(    1, pCurLeaf->uEbx, BMI2,       X86_CPUID_STEXT_FEATURE_EBX_BMI2);
                     PORTABLE_DISABLE_FEATURE_BIT(    1, pCurLeaf->uEbx, INVPCID,    X86_CPUID_STEXT_FEATURE_EBX_INVPCID);
@@ -2864,6 +2880,8 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
                 }
 
                 /* Force standard feature bits. */
+                if (pConfig->enmAvx2 == CPUMISAEXTCFG_ENABLED_ALWAYS)
+                    pCurLeaf->uEbx |= X86_CPUID_STEXT_FEATURE_EBX_AVX2;
                 if (pConfig->enmRdSeed == CPUMISAEXTCFG_ENABLED_ALWAYS)
                     pCurLeaf->uEbx |= X86_CPUID_STEXT_FEATURE_EBX_RDSEED;
                 if (pConfig->enmCLFlushOpt == CPUMISAEXTCFG_ENABLED_ALWAYS)
@@ -2981,14 +2999,59 @@ static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
      *
      * Clear them all as we don't currently implement extended CPU state.
      */
-    uSubLeaf = 0;
-    while ((pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 13, uSubLeaf)) != NULL)
+    /* Figure out the supported XCR0/XSS mask component. */
+    uint64_t fGuestXcr0Mask = 0;
+    pStdFeatureLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 1, 0);
+    if (pStdFeatureLeaf && (pStdFeatureLeaf->uEcx & X86_CPUID_FEATURE_ECX_XSAVE))
     {
-        pCurLeaf->uEax = 0;
-        pCurLeaf->uEbx = 0;
-        pCurLeaf->uEcx = 0;
-        pCurLeaf->uEdx = 0;
-        uSubLeaf++;
+        fGuestXcr0Mask = XSAVE_C_X87 | XSAVE_C_SSE;
+        if (pStdFeatureLeaf && (pStdFeatureLeaf->uEcx & X86_CPUID_FEATURE_ECX_AVX))
+            fGuestXcr0Mask |= XSAVE_C_YMM;
+        pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 7, 0);
+        if (pCurLeaf && (pCurLeaf->uEbx & X86_CPUID_STEXT_FEATURE_EBX_AVX512F))
+            fGuestXcr0Mask |= XSAVE_C_ZMM_16HI | XSAVE_C_ZMM_HI256 | XSAVE_C_OPMASK;
+        fGuestXcr0Mask &= pCpum->fXStateHostMask;
+    }
+    pStdFeatureLeaf = NULL;
+    pCpum->fXStateGuestMask = fGuestXcr0Mask;
+
+    /* Work the sub-leaves. */
+    for (uSubLeaf = 0; uSubLeaf < 63; uSubLeaf++)
+    {
+        pCurLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 13, uSubLeaf);
+        if (pCurLeaf)
+        {
+            if (fGuestXcr0Mask)
+            {
+                switch (uSubLeaf)
+                {
+                    case 0:
+                        pCurLeaf->uEax &= RT_LO_U32(fGuestXcr0Mask);
+                        pCurLeaf->uEdx &= RT_HI_U32(fGuestXcr0Mask);
+                        continue;
+                    case 1:
+                        pCurLeaf->uEax &= 0;
+                        pCurLeaf->uEcx &= 0;
+                        pCurLeaf->uEdx &= 0;
+                        continue;
+                    default:
+                        if (fGuestXcr0Mask & RT_BIT_64(uSubLeaf))
+                        {
+                            AssertLogRel(!(pCurLeaf->uEcx & 1));
+                            pCurLeaf->uEcx = 0; /* Bit 0 should be zero (XCR0), the reset are reserved... */
+                            pCurLeaf->uEdx = 0; /* it's reserved... */
+                            continue;
+                        }
+                        break;
+                }
+            }
+
+            /* Clear the leaf. */
+            pCurLeaf->uEax = 0;
+            pCurLeaf->uEbx = 0;
+            pCurLeaf->uEcx = 0;
+            pCurLeaf->uEdx = 0;
+        }
     }
 
     /* Cpuid 0xe: Marked as reserved by Intel and AMD.
@@ -3378,6 +3441,35 @@ static int cpumR3CpuIdReadIsaExtCfg(PVM pVM, PCFGMNODE pIsaExts, const char *psz
 
 
 /**
+ * Reads a value in /CPUM/IsaExts/ node, forcing it to DISABLED if wanted.
+ *
+ * @returns VBox status code (error message raised).
+ * @param   pVM             The VM handle (for errors).
+ * @param   pIsaExts        The /CPUM/IsaExts node (can be NULL).
+ * @param   pszValueName    The value / extension name.
+ * @param   penmValue       Where to return the choice.
+ * @param   enmDefault      The default choice.
+ * @param   fAllowed        Allowed choice.  Applied both to the result and to
+ *                          the default value.
+ */
+static int cpumR3CpuIdReadIsaExtCfgEx(PVM pVM, PCFGMNODE pIsaExts, const char *pszValueName,
+                                      CPUMISAEXTCFG *penmValue, CPUMISAEXTCFG enmDefault, bool fAllowed)
+{
+    int rc;
+    if (fAllowed)
+        rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, pszValueName, penmValue, enmDefault);
+    else
+    {
+        rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, pszValueName, penmValue, false /*enmDefault*/);
+        if (RT_SUCCESS(rc) && *penmValue == CPUMISAEXTCFG_ENABLED_ALWAYS)
+            LogRel(("CPUM: Ignoring forced '%s'\n", pszValueName));
+        *penmValue = CPUMISAEXTCFG_DISABLED;
+    }
+    return rc;
+}
+
+
+/**
  * Reads a value in /CPUM/IsaExts/ node that used to be located in /CPUM/.
  *
  * @returns VBox status code (error message raised).
@@ -3550,6 +3642,42 @@ static int cpumR3CpuIdReadConfig(PVM pVM, PCPUMCPUIDCONFIG pConfig, PCFGMNODE pC
     rc = cpumR3CpuIdReadIsaExtCfgLegacy(pVM, pIsaExts, pCpumCfg, "SSE4.2", &pConfig->enmSse42, true);
     AssertLogRelRCReturn(rc, rc);
 
+#if 0 /* Incomplete, so not yet enabled.  */
+    bool const fMayHaveXSave = fNestedPagingAndFullGuestExec
+                            && pVM->cpum.s.HostFeatures.fXSaveRstor
+                            && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor
+                            && pVM->cpum.s.HostFeatures.enmCpuVendor == CPUMCPUVENDOR_INTEL /** @todo test and enable on AMD! */;
+#else
+    bool const fMayHaveXSave = false;
+#endif
+    /** @cfgm{/CPUM/IsaExts/XSAVE, boolean, depends}
+     * Expose XSAVE/XRSTOR to the guest if available.  For the time being the
+     * default is to only expose this to VMs with nested paging and AMD-V or
+     * unrestricted guest execution mode.  Not possible to force this one without
+     * host support at the moment.
+     */
+    rc = cpumR3CpuIdReadIsaExtCfgEx(pVM, pIsaExts, "XSAVE", &pConfig->enmXSave, fNestedPagingAndFullGuestExec,
+                                    fMayHaveXSave /*fAllowed*/);
+    AssertLogRelRCReturn(rc, rc);
+
+    /** @cfgm{/CPUM/IsaExts/AVX, boolean, depends}
+     * Expose the AVX instruction set extensions to the guest if available and
+     * XSAVE is exposed too.  For the time being the default is to only expose this
+     * to VMs with nested paging and AMD-V or unrestricted guest execution mode.
+     */
+    rc = cpumR3CpuIdReadIsaExtCfgEx(pVM, pIsaExts, "AVX", &pConfig->enmAvx, fNestedPagingAndFullGuestExec,
+                                    fMayHaveXSave && pConfig->enmXSave /*fAllowed*/);
+    AssertLogRelRCReturn(rc, rc);
+
+    /** @cfgm{/CPUM/IsaExts/AVX2, boolean, depends}
+     * Expose the AVX2 instruction set extensions to the guest if available and
+     * XSAVE is exposed too. For the time being the default is to only expose this
+     * to VMs with nested paging and AMD-V or unrestricted guest execution mode.
+     */
+    rc = cpumR3CpuIdReadIsaExtCfgEx(pVM, pIsaExts, "AVX2", &pConfig->enmAvx2, fNestedPagingAndFullGuestExec,
+                                    fMayHaveXSave && pConfig->enmXSave /*fAllowed*/);
+    AssertLogRelRCReturn(rc, rc);
+
     /** @cfgm{/CPUM/IsaExts/AESNI, isaextcfg, depends}
      * Whether to expose the AES instructions to the guest.  For the time being the
      * default is to only do this for VMs with nested paging and AMD-V or
@@ -4521,7 +4649,7 @@ int cpumR3LoadCpuIdInner(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCPUMCPUID
     CPUID_GST_FEATURE_RET(Std, uEcx, X86_CPUID_FEATURE_ECX_TSCDEADL);
     CPUID_GST_FEATURE_RET(Std, uEcx, X86_CPUID_FEATURE_ECX_AES);     // -> EMU
     CPUID_GST_FEATURE_RET(Std, uEcx, X86_CPUID_FEATURE_ECX_XSAVE);   // -> EMU
-    CPUID_GST_FEATURE_RET(Std, uEcx, X86_CPUID_FEATURE_ECX_OSXSAVE); // -> EMU
+    CPUID_GST_FEATURE_IGN(Std, uEcx, X86_CPUID_FEATURE_ECX_OSXSAVE);
     CPUID_GST_FEATURE_RET(Std, uEcx, X86_CPUID_FEATURE_ECX_AVX);     // -> EMU?
     CPUID_GST_FEATURE_RET(Std, uEcx, X86_CPUID_FEATURE_ECX_F16C);
     CPUID_GST_FEATURE_RET(Std, uEcx, X86_CPUID_FEATURE_ECX_RDRAND);
@@ -4641,7 +4769,73 @@ int cpumR3LoadCpuIdInner(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCPUMCPUID
 
     /** @todo check leaf 7   */
 
-    /** @todo XSAVE: Stricter XSAVE feature checks for all modes. */
+    /* CPUID(d) - XCR0 stuff - takes ECX as input.
+     * ECX=0:   EAX - Valid bits in XCR0[31:0].
+     *          EBX - Maximum state size as per current XCR0 value.
+     *          ECX - Maximum state size for all supported features.
+     *          EDX - Valid bits in XCR0[63:32].
+     * ECX=1:   EAX - Various X-features.
+     *          EBX - Maximum state size as per current XCR0|IA32_XSS value.
+     *          ECX - Valid bits in IA32_XSS[31:0].
+     *          EDX - Valid bits in IA32_XSS[63:32].
+     * ECX=N, where N in 2..63 and indicates a bit in XCR0 and/or IA32_XSS,
+     *        if the bit invalid all four registers are set to zero.
+     *          EAX - The state size for this feature.
+     *          EBX - The state byte offset of this feature.
+     *          ECX - Bit 0 indicates whether this sub-leaf maps to a valid IA32_XSS bit (=1) or a valid XCR0 bit (=0).
+     *          EDX - Reserved, but is set to zero if invalid sub-leaf index.
+     */
+    PCPUMCPUIDLEAF pCurLeaf = cpumR3CpuIdGetLeaf(paLeaves, cLeaves, UINT32_C(0x0000000d), 0);
+    if (   pCurLeaf
+        && (aGuestCpuIdStd[1].uEcx & X86_CPUID_FEATURE_ECX_XSAVE)
+        && (   pCurLeaf->uEax
+            || pCurLeaf->uEbx
+            || pCurLeaf->uEcx
+            || pCurLeaf->uEdx) )
+    {
+        uint64_t fGuestXcr0Mask = RT_MAKE_U64(pCurLeaf->uEax, pCurLeaf->uEdx);
+        if (fGuestXcr0Mask & ~pVM->cpum.s.fXStateHostMask)
+            return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS,
+                                     N_("CPUID(0xd/0).EDX:EAX mismatch: %#llx saved, %#llx supported by the current host (XCR0 bits)"),
+                                     fGuestXcr0Mask, pVM->cpum.s.fXStateHostMask);
+
+        /* We don't support any additional features yet. */
+        pCurLeaf = cpumR3CpuIdGetLeaf(paLeaves, cLeaves, UINT32_C(0x0000000d), 1);
+        if (pCurLeaf && pCurLeaf->uEax)
+            return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS,
+                                     N_("CPUID(0xd/1).EAX=%#x, expected zero"), pCurLeaf->uEax);
+        if (pCurLeaf && (pCurLeaf->uEcx || pCurLeaf->uEdx))
+            return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS,
+                                     N_("CPUID(0xd/1).EDX:ECX=%#llx, expected zero"),
+                                     RT_MAKE_U64(pCurLeaf->uEdx, pCurLeaf->uEcx));
+
+
+        if (pVM->cpum.s.fXStateGuestMask != fGuestXcr0Mask)
+        {
+            LogRel(("CPUM: fXStateGuestMask=%#lx -> %#llx\n", pVM->cpum.s.fXStateGuestMask, fGuestXcr0Mask));
+            pVM->cpum.s.fXStateGuestMask = fGuestXcr0Mask;
+        }
+
+        for (uint32_t uSubLeaf = 2; uSubLeaf < 64; uSubLeaf++)
+        {
+            pCurLeaf = cpumR3CpuIdGetLeaf(paLeaves, cLeaves, UINT32_C(0x0000000d), uSubLeaf);
+            if (pCurLeaf)
+            {
+                /* If advertised, the state component offset and size must match the one used by host. */
+                if (pCurLeaf->uEax || pCurLeaf->uEbx || pCurLeaf->uEcx || pCurLeaf->uEdx)
+                {
+                    CPUMCPUID RawHost;
+                    ASMCpuIdExSlow(UINT32_C(0x0000000d), 0, uSubLeaf, 0,
+                                   &RawHost.uEax, &RawHost.uEbx, &RawHost.uEcx, &RawHost.uEdx);
+                    if (   RawHost.uEbx != pCurLeaf->uEbx
+                        || RawHost.uEax != pCurLeaf->uEax)
+                        return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS,
+                                                 N_("CPUID(0xd/%#x).EBX/EAX=%#x/%#x, current host uses %#x/%#x (offset/size)"),
+                                                 uSubLeaf, pCurLeaf->uEbx, pCurLeaf->uEax, RawHost.uEbx, RawHost.uEax);
+                }
+            }
+        }
+    }
 
 #undef CPUID_CHECK_RET
 #undef CPUID_CHECK_WRN
diff --git a/src/VBox/VMM/VMMR3/GIM.cpp b/src/VBox/VMM/VMMR3/GIM.cpp
index 4219622..45af17a 100644
--- a/src/VBox/VMM/VMMR3/GIM.cpp
+++ b/src/VBox/VMM/VMMR3/GIM.cpp
@@ -141,7 +141,6 @@ VMMR3_INT_DECL(int) GIMR3Init(PVM pVM)
             pVM->gim.s.enmProviderId = GIMPROVIDERID_KVM;
             rc = gimR3KvmInit(pVM);
         }
-        /** @todo KVM and others. */
         else
             rc = VMR3SetError(pVM->pUVM, VERR_GIM_INVALID_PROVIDER, RT_SRC_POS, "Provider \"%s\" unknown.", szProvider);
     }
diff --git a/src/VBox/VMM/VMMR3/GIMHv.cpp b/src/VBox/VMM/VMMR3/GIMHv.cpp
index bfe44f9..409441d 100644
--- a/src/VBox/VMM/VMMR3/GIMHv.cpp
+++ b/src/VBox/VMM/VMMR3/GIMHv.cpp
@@ -632,6 +632,8 @@ VMMR3_INT_DECL(int) gimR3HvDisableHypercallPage(PVM pVM)
     {
         GIMR3Mmio2Unmap(pVM, pRegion);
         Assert(!pRegion->fMapped);
+        for (VMCPUID i = 0; i < pVM->cCpus; i++)
+            VMMHypercallsDisable(&pVM->aCpus[i]);
         LogRel(("GIM: HyperV: Disabled Hypercall-page\n"));
         return VINF_SUCCESS;
     }
@@ -679,36 +681,34 @@ VMMR3_INT_DECL(int) gimR3HvEnableHypercallPage(PVM pVM, RTGCPHYS GCPhysHypercall
         /*
          * Patch the hypercall-page.
          */
-        if (HMIsEnabled(pVM))
+        size_t cbWritten = 0;
+        rc = VMMPatchHypercall(pVM, pRegion->pvPageR3, PAGE_SIZE, &cbWritten);
+        if (   RT_SUCCESS(rc)
+            && cbWritten < PAGE_SIZE)
         {
-            size_t cbWritten = 0;
-            rc = HMPatchHypercall(pVM, pRegion->pvPageR3, PAGE_SIZE, &cbWritten);
-            if (   RT_SUCCESS(rc)
-                && cbWritten < PAGE_SIZE)
-            {
-                uint8_t *pbLast = (uint8_t *)pRegion->pvPageR3 + cbWritten;
-                *pbLast = 0xc3;  /* RET */
-
-                LogRel(("GIM: HyperV: Enabled hypercalls at %#RGp\n", GCPhysHypercallPage));
-                return VINF_SUCCESS;
-            }
-            else
-            {
-                if (rc == VINF_SUCCESS)
-                    rc = VERR_GIM_OPERATION_FAILED;
-                LogRelFunc(("HMPatchHypercall failed. rc=%Rrc cbWritten=%u\n", rc, cbWritten));
-            }
+            uint8_t *pbLast = (uint8_t *)pRegion->pvPageR3 + cbWritten;
+            *pbLast = 0xc3;  /* RET */
+
+            /*
+             * Notify VMM that hypercalls are now enabled for all VCPUs.
+             */
+            for (VMCPUID i = 0; i < pVM->cCpus; i++)
+                VMMHypercallsEnable(&pVM->aCpus[i]);
+
+            LogRel(("GIM: HyperV: Enabled hypercalls at %#RGp\n", GCPhysHypercallPage));
+            return VINF_SUCCESS;
         }
         else
         {
-            /** @todo Handle raw-mode hypercall page patching. */
-            LogRel(("GIM: HyperV: Raw-mode hypercalls not yet implemented!\n"));
+            if (rc == VINF_SUCCESS)
+                rc = VERR_GIM_OPERATION_FAILED;
+            LogRel(("GIM: HyperV: VMMPatchHypercall failed. rc=%Rrc cbWritten=%u\n", rc, cbWritten));
         }
+
         GIMR3Mmio2Unmap(pVM, pRegion);
     }
-    else
-        LogRelFunc(("GIMR3Mmio2Map failed. rc=%Rrc\n", rc));
 
+    LogRel(("GIM: HyperV: GIMR3Mmio2Map failed. rc=%Rrc\n", rc));
     return rc;
 }
 
diff --git a/src/VBox/VMM/VMMR3/GIMKvm.cpp b/src/VBox/VMM/VMMR3/GIMKvm.cpp
index cb35746..1ce191f 100644
--- a/src/VBox/VMM/VMMR3/GIMKvm.cpp
+++ b/src/VBox/VMM/VMMR3/GIMKvm.cpp
@@ -29,6 +29,7 @@
 #include <iprt/spinlock.h>
 
 #include <VBox/vmm/cpum.h>
+#include <VBox/disopcode.h>
 #include <VBox/vmm/ssm.h>
 #include <VBox/vmm/vm.h>
 #include <VBox/vmm/hm.h>
@@ -140,6 +141,28 @@ VMMR3_INT_DECL(int) gimR3KvmInit(PVM pVM)
         AssertLogRelRCReturn(rc, rc);
     }
 
+    /*
+     * Setup hypercall and #UD handling.
+     */
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+        VMMHypercallsEnable(&pVM->aCpus[i]);
+
+    if (ASMIsAmdCpu())
+    {
+        pKvm->fTrapXcptUD   = true;
+        pKvm->uOpCodeNative = OP_VMMCALL;
+    }
+    else
+    {
+        Assert(ASMIsIntelCpu() || ASMIsViaCentaurCpu());
+        pKvm->fTrapXcptUD   = false;
+        pKvm->uOpCodeNative = OP_VMCALL;
+    }
+
+    /* We always need to trap VMCALL/VMMCALL hypercall using #UDs for raw-mode VMs. */
+    if (!HMIsEnabled(pVM))
+        pKvm->fTrapXcptUD = true;
+
     return VINF_SUCCESS;
 }
 
@@ -367,8 +390,8 @@ VMMR3_INT_DECL(int) gimR3KvmEnableSystemTime(PVM pVM, PVMCPU pVCpu, PGIMKVMCPU p
      *     tsc >>= -i8TscShift;
      * time = ((tsc * SysTime.u32TscScale) >> 32) + SysTime.u64NanoTS
      */
-    uint64_t u64TscFreq = TMCpuTicksPerSecond(pVM);
-    SystemTime.i8TscShift  = 0;
+    uint64_t u64TscFreq   = TMCpuTicksPerSecond(pVM);
+    SystemTime.i8TscShift = 0;
     while (u64TscFreq > 2 * RT_NS_1SEC_64)
     {
         u64TscFreq >>= 1;
diff --git a/src/VBox/VMM/VMMR3/HM.cpp b/src/VBox/VMM/VMMR3/HM.cpp
index af677be..685a528 100644
--- a/src/VBox/VMM/VMMR3/HM.cpp
+++ b/src/VBox/VMM/VMMR3/HM.cpp
@@ -119,7 +119,12 @@ static const char * const g_apszVTxExitReasons[MAX_EXITREASON_STAT] =
     EXIT_REASON_NIL(),
     EXIT_REASON(VMX_EXIT_RDRAND             , 57, "RDRAND instruction."),
     EXIT_REASON(VMX_EXIT_INVPCID            , 58, "INVPCID instruction."),
-    EXIT_REASON(VMX_EXIT_VMFUNC             , 59, "VMFUNC instruction.")
+    EXIT_REASON(VMX_EXIT_VMFUNC             , 59, "VMFUNC instruction."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_RDSEED             , 61, "RDSEED instruction."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_XSAVES             , 61, "XSAVES instruction."),
+    EXIT_REASON(VMX_EXIT_XRSTORS            , 62, "XRSTORS instruction.")
 };
 /** Exit reason descriptions for AMD-V, used to describe statistics. */
 static const char * const g_apszAmdVExitReasons[MAX_EXITREASON_STAT] =
diff --git a/src/VBox/VMM/VMMR3/IEMR3.cpp b/src/VBox/VMM/VMMR3/IEMR3.cpp
index af847f7..96be7b4 100644
--- a/src/VBox/VMM/VMMR3/IEMR3.cpp
+++ b/src/VBox/VMM/VMMR3/IEMR3.cpp
@@ -70,21 +70,12 @@ VMMR3DECL(int)      IEMR3Init(PVM pVM)
          */
         if (idCpu == 0)
         {
-            uint32_t uIgnored;
-            CPUMGetGuestCpuId(pVCpu, 1, 0, &uIgnored, &uIgnored,
-                              &pVCpu->iem.s.fCpuIdStdFeaturesEcx, &pVCpu->iem.s.fCpuIdStdFeaturesEdx);
             pVCpu->iem.s.enmCpuVendor             = CPUMGetGuestCpuVendor(pVM);
-
-            ASMCpuId_ECX_EDX(1, &pVCpu->iem.s.fHostCpuIdStdFeaturesEcx, &pVCpu->iem.s.fHostCpuIdStdFeaturesEdx);
             pVCpu->iem.s.enmHostCpuVendor         = CPUMGetHostCpuVendor(pVM);
         }
         else
         {
-            pVCpu->iem.s.fCpuIdStdFeaturesEcx     = pVM->aCpus[0].iem.s.fCpuIdStdFeaturesEcx;
-            pVCpu->iem.s.fCpuIdStdFeaturesEdx     = pVM->aCpus[0].iem.s.fCpuIdStdFeaturesEdx;
             pVCpu->iem.s.enmCpuVendor             = pVM->aCpus[0].iem.s.enmCpuVendor;
-            pVCpu->iem.s.fHostCpuIdStdFeaturesEcx = pVM->aCpus[0].iem.s.fHostCpuIdStdFeaturesEcx;
-            pVCpu->iem.s.fHostCpuIdStdFeaturesEdx = pVM->aCpus[0].iem.s.fHostCpuIdStdFeaturesEdx;
             pVCpu->iem.s.enmHostCpuVendor         = pVM->aCpus[0].iem.s.enmHostCpuVendor;
         }
 
diff --git a/src/VBox/VMM/VMMR3/PDMBlkCache.cpp b/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
index b57e4dd..cd1c188 100644
--- a/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
+++ b/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
@@ -923,7 +923,7 @@ static DECLCALLBACK(int) pdmR3BlkCacheLoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_
             break;
         }
 
-        RTStrFree(pszId);
+        RTMemFree(pszId);
         pszId = NULL;
 
         while (cEntries > 0)
@@ -966,7 +966,7 @@ static DECLCALLBACK(int) pdmR3BlkCacheLoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_
     }
 
     if (pszId)
-        RTStrFree(pszId);
+        RTMemFree(pszId);
 
     if (cRefs && RT_SUCCESS(rc))
         rc = SSMR3SetCfgError(pSSM, RT_SRC_POS,
@@ -1913,8 +1913,6 @@ static bool pdmBlkCacheReqUpdate(PPDMBLKCACHE pBlkCache, PPDMBLKCACHEREQ pReq,
     {
         if (fCallHandler)
             pdmBlkCacheReqComplete(pBlkCache, pReq);
-        else
-            RTMemFree(pReq);
         return true;
     }
 
@@ -2132,6 +2130,11 @@ VMMR3DECL(int) PDMR3BlkCacheRead(PPDMBLKCACHE pBlkCache, uint64_t off,
 
     if (!pdmBlkCacheReqUpdate(pBlkCache, pReq, rc, false))
         rc = VINF_AIO_TASK_PENDING;
+    else
+    {
+        rc = pReq->rcReq;
+        RTMemFree(pReq);
+    }
 
     LogFlowFunc((": Leave rc=%Rrc\n", rc));
 
@@ -2360,6 +2363,11 @@ VMMR3DECL(int) PDMR3BlkCacheWrite(PPDMBLKCACHE pBlkCache, uint64_t off,
 
     if (!pdmBlkCacheReqUpdate(pBlkCache, pReq, rc, false))
         rc = VINF_AIO_TASK_PENDING;
+    else
+    {
+        rc = pReq->rcReq;
+        RTMemFree(pReq);
+    }
 
     LogFlowFunc((": Leave rc=%Rrc\n", rc));
 
@@ -2536,6 +2544,11 @@ VMMR3DECL(int) PDMR3BlkCacheDiscard(PPDMBLKCACHE pBlkCache, PCRTRANGE paRanges,
 
     if (!pdmBlkCacheReqUpdate(pBlkCache, pReq, rc, false))
         rc = VINF_AIO_TASK_PENDING;
+    else
+    {
+        rc = pReq->rcReq;
+        RTMemFree(pReq);
+    }
 
     LogFlowFunc((": Leave rc=%Rrc\n", rc));
 
diff --git a/src/VBox/VMM/VMMR3/PGM.cpp b/src/VBox/VMM/VMMR3/PGM.cpp
index a3d922f..3eb381b 100644
--- a/src/VBox/VMM/VMMR3/PGM.cpp
+++ b/src/VBox/VMM/VMMR3/PGM.cpp
@@ -1631,9 +1631,9 @@ static int pgmR3InitPaging(PVM pVM)
     {
         LogFlow(("pgmR3InitPaging: returns successfully\n"));
 #if HC_ARCH_BITS == 64
-        LogRel(("Debug: HCPhysInterPD=%RHp HCPhysInterPaePDPT=%RHp HCPhysInterPaePML4=%RHp\n",
+        LogRel(("PGM: HCPhysInterPD=%RHp HCPhysInterPaePDPT=%RHp HCPhysInterPaePML4=%RHp\n",
                 pVM->pgm.s.HCPhysInterPD, pVM->pgm.s.HCPhysInterPaePDPT, pVM->pgm.s.HCPhysInterPaePML4));
-        LogRel(("Debug: apInterPTs={%RHp,%RHp} apInterPaePTs={%RHp,%RHp} apInterPaePDs={%RHp,%RHp,%RHp,%RHp} pInterPaePDPT64=%RHp\n",
+        LogRel(("PGM: apInterPTs={%RHp,%RHp} apInterPaePTs={%RHp,%RHp} apInterPaePDs={%RHp,%RHp,%RHp,%RHp} pInterPaePDPT64=%RHp\n",
                 MMPage2Phys(pVM, pVM->pgm.s.apInterPTs[0]),    MMPage2Phys(pVM, pVM->pgm.s.apInterPTs[1]),
                 MMPage2Phys(pVM, pVM->pgm.s.apInterPaePTs[0]), MMPage2Phys(pVM, pVM->pgm.s.apInterPaePTs[1]),
                 MMPage2Phys(pVM, pVM->pgm.s.apInterPaePDs[0]), MMPage2Phys(pVM, pVM->pgm.s.apInterPaePDs[1]), MMPage2Phys(pVM, pVM->pgm.s.apInterPaePDs[2]), MMPage2Phys(pVM, pVM->pgm.s.apInterPaePDs[3]),
diff --git a/src/VBox/VMM/VMMR3/PGMPool.cpp b/src/VBox/VMM/VMMR3/PGMPool.cpp
index 6afc27e..15a005a 100644
--- a/src/VBox/VMM/VMMR3/PGMPool.cpp
+++ b/src/VBox/VMM/VMMR3/PGMPool.cpp
@@ -173,7 +173,7 @@ int pgmR3PoolInit(PVM pVM)
     cMaxPages = RT_ALIGN(cMaxPages, 16);
     if (cMaxPages > PGMPOOL_IDX_LAST)
         cMaxPages = PGMPOOL_IDX_LAST;
-    LogRel(("PGMPool: cMaxPages=%u (u64MaxPages=%llu)\n", cMaxPages, u64MaxPages));
+    LogRel(("PGM: PGMPool: cMaxPages=%u (u64MaxPages=%llu)\n", cMaxPages, u64MaxPages));
 
     /** todo:
      * We need to be much more careful with our allocation strategy here.
@@ -219,7 +219,7 @@ int pgmR3PoolInit(PVM pVM)
     rc = CFGMR3QueryBoolDef(pCfg, "CacheEnabled", &fCacheEnabled, true);
     AssertLogRelRCReturn(rc, rc);
 
-    LogRel(("pgmR3PoolInit: cMaxPages=%#RX16 cMaxUsers=%#RX16 cMaxPhysExts=%#RX16 fCacheEnable=%RTbool\n",
+    LogRel(("PGM: pgmR3PoolInit: cMaxPages=%#RX16 cMaxUsers=%#RX16 cMaxPhysExts=%#RX16 fCacheEnable=%RTbool\n",
              cMaxPages, cMaxUsers, cMaxPhysExts, fCacheEnabled));
 
     /*
diff --git a/src/VBox/VMM/VMMR3/TM.cpp b/src/VBox/VMM/VMMR3/TM.cpp
index c885b86..2b0a318 100644
--- a/src/VBox/VMM/VMMR3/TM.cpp
+++ b/src/VBox/VMM/VMMR3/TM.cpp
@@ -264,9 +264,9 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM)
                           pGip->u32UpdateIntervalNS, pGip->u32UpdateHz);
 
     /* Log GIP info that may come in handy. */
-    LogRel(("TM: GIP - u32Mode=%d (%s) u32UpdateHz=%u u32UpdateIntervalNS=%u enmUseTscDelta=%d fGetGipCpu=%#x cCpus=%d\n",
+    LogRel(("TM: GIP - u32Mode=%d (%s) u32UpdateHz=%u u32UpdateIntervalNS=%u enmUseTscDelta=%d (%s) fGetGipCpu=%#x cCpus=%d\n",
             pGip->u32Mode, SUPGetGIPModeName(pGip), pGip->u32UpdateHz, pGip->u32UpdateIntervalNS,
-            pGip->enmUseTscDelta, pGip->fGetGipCpu, pGip->cCpus));
+            pGip->enmUseTscDelta, SUPGetGIPTscDeltaModeName(pGip), pGip->fGetGipCpu, pGip->cCpus));
     LogRel(("TM: GIP - u64CpuHz=%'RU64 (%#RX64)  SUPGetCpuHzFromGip => %'RU64\n",
             pGip->u64CpuHz, pGip->u64CpuHz, SUPGetCpuHzFromGip(pGip)));
     for (uint32_t iCpuSet = 0; iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx); iCpuSet++)
@@ -289,7 +289,7 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM)
     pVM->tm.s.VirtualGetRawDataRC.pu64Prev       = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
     pVM->tm.s.VirtualGetRawDataR0.pu64Prev       = MMHyperR3ToR0(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
     AssertRelease(pVM->tm.s.VirtualGetRawDataR0.pu64Prev);
-    /* The rest is done in TMR3InitFinalize since it's too early to call PDM. */
+    /* The rest is done in TMR3InitFinalize() since it's too early to call PDM. */
 
     /*
      * Init the locks.
@@ -817,7 +817,7 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM)
  *
  * @returns true if it has, false if it hasn't.
  *
- * @remark  This test doesn't bother with very old CPUs that don't do power
+ * @remarks This test doesn't bother with very old CPUs that don't do power
  *          management or any other stuff that might influence the TSC rate.
  *          This isn't currently relevant.
  */
@@ -882,6 +882,7 @@ static bool tmR3HasFixedTSC(PVM pVM)
              * This test is lacking in the same way and for the same reasons
              * as the AMD test above.
              */
+            /** @todo use ASMGetCpuFamily() and ASMGetCpuModel() here. */
             ASMCpuId(1, &uEAX, &uEBX, &uECX, &uEDX);
             unsigned uModel  = (uEAX >> 4) & 0x0f;
             unsigned uFamily = (uEAX >> 8) & 0x0f;
@@ -901,6 +902,7 @@ static bool tmR3HasFixedTSC(PVM pVM)
              * This only checks for VIA CPU models Nano X2, Nano X3,
              * Eden X2 and QuadCore.
              */
+            /** @todo use ASMGetCpuFamily() and ASMGetCpuModel() here. */
             ASMCpuId(1, &uEAX, &uEBX, &uECX, &uEDX);
             unsigned uStepping = (uEAX & 0x0f);
             unsigned uModel    = (uEAX >> 4) & 0x0f;
@@ -1047,6 +1049,7 @@ VMM_INT_DECL(int) TMR3InitFinalize(PVM pVM)
      * GIM is now initialized. Determine if TSC mode switching is allowed (respecting CFGM override).
      */
     pVM->tm.s.fTSCModeSwitchAllowed &= tmR3HasFixedTSC(pVM) && GIMIsEnabled(pVM) && HMIsEnabled(pVM);
+    LogRel(("TM: TMR3InitFinalize: fTSCModeSwitchAllowed=%RTbool\n", pVM->tm.s.fTSCModeSwitchAllowed));
     return rc;
 }
 
@@ -3136,7 +3139,7 @@ VMMR3_INT_DECL(int) TMR3CpuTickParavirtEnable(PVM pVM)
             rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, tmR3CpuTickParavirtEnable, NULL);
     }
     else
-        LogRel(("TM: Host is not suitable for using TSC mode (%d - %s). Request to change TSC mode ignored.\n",
+        LogRel(("TM: Host/VM is not suitable for using TSC mode %d (%s). Request to change TSC mode ignored.\n",
                 TMTSCMODE_REAL_TSC_OFFSET, tmR3GetTSCModeNameEx(TMTSCMODE_REAL_TSC_OFFSET)));
     pVM->tm.s.fParavirtTscEnabled = true;
     return rc;
diff --git a/src/VBox/VMM/VMMR3/VMM.cpp b/src/VBox/VMM/VMMR3/VMM.cpp
index c985e29..b424fc2 100644
--- a/src/VBox/VMM/VMMR3/VMM.cpp
+++ b/src/VBox/VMM/VMMR3/VMM.cpp
@@ -543,7 +543,7 @@ VMMR3_INT_DECL(int) VMMR3InitR0(PVM pVM)
     if (pVM->aCpus[0].vmm.s.hR0ThreadCtx != NIL_RTTHREADCTX)
         LogRel(("VMM: Thread-context hooks enabled!\n"));
     else
-        LogRel(("VMM: Thread-context hooks unavailable.\n"));
+        LogRel(("VMM: Thread-context hooks unavailable\n"));
 
     return rc;
 }
diff --git a/src/VBox/VMM/VMMR3/VMMSwitcher.cpp b/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
index 3cdd5cb..5730b24 100644
--- a/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
+++ b/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
@@ -282,11 +282,11 @@ int vmmR3SwitcherInit(PVM pVM)
                 paBadTries[i].HCPhys = pVM->vmm.s.HCPhysCoreCode;
                 paBadTries[i].cb     = pVM->vmm.s.cbCoreCode;
                 i++;
-                LogRel(("Failed to allocated and map core code: rc=%Rrc\n", rc));
+                LogRel(("VMM: Failed to allocated and map core code: rc=%Rrc\n", rc));
             }
             while (i-- > 0)
             {
-                LogRel(("Core code alloc attempt #%d: pvR3=%p pvR0=%p HCPhys=%RHp\n",
+                LogRel(("VMM: Core code alloc attempt #%d: pvR3=%p pvR0=%p HCPhys=%RHp\n",
                         i, paBadTries[i].pvR3, paBadTries[i].pvR0, paBadTries[i].HCPhys));
                 SUPR3ContFree(paBadTries[i].pvR3, paBadTries[i].cb >> PAGE_SHIFT);
             }
@@ -324,7 +324,7 @@ int vmmR3SwitcherInit(PVM pVM)
         {
             pVM->vmm.s.pvCoreCodeRC = GCPtr;
             MMR3HyperReserve(pVM, PAGE_SIZE, "fence", NULL);
-            LogRel(("CoreCode: R3=%RHv R0=%RHv RC=%RRv Phys=%RHp cb=%#x\n",
+            LogRel(("VMM: CoreCode: R3=%RHv R0=%RHv RC=%RRv Phys=%RHp cb=%#x\n",
                     pVM->vmm.s.pvCoreCodeR3, pVM->vmm.s.pvCoreCodeR0, pVM->vmm.s.pvCoreCodeRC, pVM->vmm.s.HCPhysCoreCode, pVM->vmm.s.cbCoreCode));
 
             /*
diff --git a/src/VBox/VMM/VMMRC/CPUMRCA.asm b/src/VBox/VMM/VMMRC/CPUMRCA.asm
index c644820..e84e5a6 100644
--- a/src/VBox/VMM/VMMRC/CPUMRCA.asm
+++ b/src/VBox/VMM/VMMRC/CPUMRCA.asm
@@ -144,10 +144,27 @@ hlfpua_switch_fpu_ctx:
         and     edx, ~(X86_CR0_TS | X86_CR0_EM)
         mov     cr0, edx                ; Clear flags so we don't trap here.
 
+        mov     eax, [pCpumCpu + CPUMCPU.Host.fXStateMask]
         mov     pXState, [pCpumCpu + CPUMCPU.Host.pXStateRC]
+        or      eax, eax
+        jz      hlfpua_host_fxsave
+        mov     edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
+        xsave   [pXState]
+        jmp     hlfpua_host_done
+hlfpua_host_fxsave:
         fxsave  [pXState]
+hlfpua_host_done:
+
+        mov     eax, [pCpumCpu + CPUMCPU.Guest.fXStateMask]
         mov     pXState, [pCpumCpu + CPUMCPU.Guest.pXStateRC]
+        or      eax, eax
+        jz      hlfpua_guest_fxrstor
+        mov     edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
+        xrstor  [pXState]
+        jmp     hlfpua_guest_done
+hlfpua_guest_fxrstor:
         fxrstor [pXState]
+hlfpua_guest_done:
 
 hlfpua_finished_switch:
         or      dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
diff --git a/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp b/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
index 2c91890..7fe898e 100644
--- a/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
+++ b/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
@@ -26,6 +26,7 @@
 #include <VBox/vmm/pdmapi.h>
 #include <VBox/vmm/dbgf.h>
 #include <VBox/vmm/em.h>
+#include <VBox/vmm/gim.h>
 #include <VBox/vmm/csam.h>
 #include <VBox/vmm/patm.h>
 #include <VBox/vmm/mm.h>
@@ -594,7 +595,7 @@ DECLASM(int) TRPMGCTrap06Handler(PTRPMCPU pTrpmCpu, PCPUMCTXCORE pRegFrame)
             Log(("TRPMGCTrap06Handler: pc=%08x op=%d\n", pRegFrame->eip, Cpu.pCurInstr->uOpcode));
 #ifdef DTRACE_EXPERIMENT /** @todo fix/remove/permanent-enable this when DIS/PATM handles invalid lock sequences. */
             Assert(!PATMIsPatchGCAddr(pVM, pRegFrame->eip));
-            rc = TRPMForwardTrap(pVCpu, pRegFrame, 0x6, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_TRAP, 0x6);
+            rc = TRPMForwardTrap(pVCpu, pRegFrame, X86_XCPT_UD, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_TRAP, X86_XCPT_UD);
             Assert(rc == VINF_EM_RAW_GUEST_TRAP);
 #else
             rc = VINF_EM_RAW_EMULATE_INSTR;
@@ -608,6 +609,16 @@ DECLASM(int) TRPMGCTrap06Handler(PTRPMCPU pTrpmCpu, PCPUMCTXCORE pRegFrame)
             LogFlow(("TRPMGCTrap06Handler: -> EMInterpretInstructionCPU\n"));
             rc = EMInterpretInstructionDisasState(pVCpu, &Cpu, pRegFrame, PC, EMCODETYPE_SUPERVISOR);
         }
+        else if (GIMShouldTrapXcptUD(pVCpu))
+        {
+            LogFlow(("TRPMGCTrap06Handler: -> GIMXcptUD\n"));
+            rc = GIMXcptUD(pVCpu, CPUMCTX_FROM_CORE(pRegFrame), &Cpu);
+            if (RT_FAILURE(rc))
+            {
+                LogFlow(("TRPMGCTrap06Handler: -> GIMXcptUD -> VINF_EM_RAW_EMULATE_INSTR\n"));
+                rc = VINF_EM_RAW_EMULATE_INSTR;
+            }
+        }
         /* Never generate a raw trap here; it might be an instruction, that requires emulation. */
         else
         {
@@ -618,7 +629,7 @@ DECLASM(int) TRPMGCTrap06Handler(PTRPMCPU pTrpmCpu, PCPUMCTXCORE pRegFrame)
     else
     {
         LogFlow(("TRPMGCTrap06Handler: -> TRPMForwardTrap\n"));
-        rc = TRPMForwardTrap(pVCpu, pRegFrame, 0x6, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_TRAP, 0x6);
+        rc = TRPMForwardTrap(pVCpu, pRegFrame, X86_XCPT_UD, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_TRAP, X86_XCPT_UD);
         Assert(rc == VINF_EM_RAW_GUEST_TRAP);
     }
 
diff --git a/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac b/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
index 011f139..7afd280 100644
--- a/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
+++ b/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
@@ -1138,16 +1138,37 @@ gth_sysenter_no:
     ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
     mov     esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
     test    esi, CPUM_USED_FPU
-    jz short gth_fpu_no
+    jz      gth_fpu_no
     mov     rcx, cr0
     and     rcx, ~(X86_CR0_TS | X86_CR0_EM)
     mov     cr0, rcx
 
-    mov     rax, [rdx + r8 + CPUMCPU.Guest.pXStateR0]
-    fxsave  [rax]
-    mov     rax, [rdx + r8 + CPUMCPU.Host.pXStateR0]
-    fxrstor [rax]                       ; We saved 32-bit state, so only restore 32-bit.
-    jmp short gth_fpu_no
+    mov     r10, rdx                    ; Save rdx.
+
+    mov     eax, [r10 + r8 + CPUMCPU.Guest.fXStateMask]
+    mov     r9, [r10 + r8 + CPUMCPU.Guest.pXStateR0]
+    or      eax, eax
+    jz      gth_fpu_guest_fxsave
+    mov     edx, [r10 + r8 + CPUMCPU.Guest.fXStateMask + 4]
+    xsave   [r9]
+    jmp     gth_fpu_host
+gth_fpu_guest_fxsave:
+    fxsave  [r9]
+
+gth_fpu_host:
+    mov     eax, [r10 + r8 + CPUMCPU.Host.fXStateMask]
+    mov     r9, [r10 + r8 + CPUMCPU.Host.pXStateR0]
+    or      eax, eax
+    jz      gth_fpu_host_fxrstor
+    mov     edx, [r10 + r8 + CPUMCPU.Host.fXStateMask + 4]
+    xrstor  [r9]                        ; We saved 32-bit state, so only restore 32-bit.
+    jmp     gth_fpu_done
+gth_fpu_host_fxrstor:
+    fxrstor [r9]                        ; We saved 32-bit state, so only restore 32-bit.
+
+gth_fpu_done:
+    mov     rdx, r10                    ; Restore rdx.
+    jmp     gth_fpu_no
 
 ALIGNCODE(16)
 gth_fpu_no:
diff --git a/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac b/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
index 3a14db9..9cc77cb 100644
--- a/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
+++ b/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
@@ -663,8 +663,19 @@ GLOBALNAME ICEnterTarget
     mov     rcx, rax                    ; save old CR0
     and     rax, ~(X86_CR0_TS | X86_CR0_EM)
     mov     cr0, rax
-    mov     eax, [rdx + CPUMCPU.Guest.pXStateRC]
-    o64 fxrstor [rax]                   ; (use explicit REX prefix, see @bugref{6398})
+
+    mov     eax, [rdx + CPUMCPU.Guest.fXStateMask]
+    mov     ebx, [rdx + CPUMCPU.Guest.pXStateRC]
+    or      eax, eax
+    jz      htg_fpu_fxrstor
+    mov     r9, rdx
+    mov     edx, [rdx + CPUMCPU.Guest.fXStateMask + 4]
+    o64 xsave [rbx]
+    mov     rdx, r9
+    jmp     htg_fpu_done
+htg_fpu_fxrstor:
+    o64 fxrstor [rbx]                   ; (use explicit REX prefix, see @bugref{6398})
+htg_fpu_done:
     mov     cr0, rcx                    ; and restore old CR0 again
 
     and     dword [rdx + CPUMCPU.fUseFlags], ~CPUM_SYNC_FPU_STATE
@@ -1257,9 +1268,18 @@ BEGINPROC HMRCSaveGuestFPU64
     and     rax, ~(X86_CR0_TS | X86_CR0_EM)
     mov     cr0, rax
 
-    mov     eax, [rsi + CPUMCTX.pXStateRC]
-    o64 fxsave  [rax]                   ; (use explicit REX prefix, see @bugref{6398})
+    mov     eax, [rsi + CPUMCTX.fXStateMask]
+    mov     ebx, [rsi + CPUMCTX.pXStateRC]
+    test    eax, eax
+    jz      .use_fxsave
+    mov     edx, [rsi + CPUMCTX.fXStateMask + 4]
+    o64 xsave [rbx]
+    jmp     .done
+
+.use_fxsave:
+    o64 fxsave  [rbx]                   ; (use explicit REX prefix, see @bugref{6398})
 
+.done:
     mov     cr0, rcx                    ; and restore old CR0 again
 
     mov     eax, VINF_SUCCESS
diff --git a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
index 00ef11e..b8d0fe0 100644
--- a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
+++ b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
@@ -989,10 +989,31 @@ gth_syscall_no:
     and     ecx, ~(X86_CR0_TS | X86_CR0_EM)
     mov     cr0, ecx
 
-    mov     eax, [edx + CPUMCPU.Guest.pXStateR0]
-    mov     ecx, [edx + CPUMCPU.Host.pXStateR0]
-    fxsave  [eax]
+    mov     ebx, edx                    ; save edx
+
+    mov     eax, [ebx + CPUMCPU.Guest.fXStateMask]
+    mov     ecx, [ebx + CPUMCPU.Guest.pXStateR0]
+    test    eax, eax
+    jz      gth_fpu_guest_fxsave
+    mov     edx, [ebx + CPUMCPU.Guest.fXStateMask + 4]
+    xsave   [ecx]
+    jmp     gth_fpu_host
+gth_fpu_guest_fxsave:
+    fxsave  [ecx]
+
+gth_fpu_host:
+    mov     eax, [ebx + CPUMCPU.Host.fXStateMask]
+    mov     ecx, [ebx + CPUMCPU.Host.pXStateR0]
+    test    eax, eax
+    jz      gth_fpu_host_fxrstor
+    mov     edx, [ebx + CPUMCPU.Host.fXStateMask + 4]
+    xrstor  [ecx]
+    jmp     gth_fpu_done
+gth_fpu_host_fxrstor:
     fxrstor [ecx]
+
+gth_fpu_done:
+    mov     edx, ebx                    ; restore edx
 gth_fpu_no:
 
     ; Control registers.
@@ -1002,7 +1023,7 @@ gth_fpu_no:
     mov     cr4, ecx
     mov     ecx, [edx + CPUMCPU.Host.cr0]
     mov     cr0, ecx
-    ;mov     ecx, [edx + CPUMCPU.Host.cr2] ; assumes this is waste of time.
+    ;mov     ecx, [edx + CPUMCPU.Host.cr2] ; assumes this is a waste of time.
     ;mov     cr2, ecx
 
     ; restore debug registers (if modified) (esi must still be fUseFlags!)
diff --git a/src/VBox/VMM/include/CPUMInternal.h b/src/VBox/VMM/include/CPUMInternal.h
index b69c3f3..a9425a2 100644
--- a/src/VBox/VMM/include/CPUMInternal.h
+++ b/src/VBox/VMM/include/CPUMInternal.h
@@ -147,113 +147,6 @@ typedef uint64_t STAMCOUNTER;
 /** @} */
 
 
-
-/**
- * CPU features and quirks.
- * This is mostly exploded CPUID info.
- */
-typedef struct CPUMFEATURES
-{
-    /** The CPU vendor (CPUMCPUVENDOR). */
-    uint8_t         enmCpuVendor;
-    /** The CPU family. */
-    uint8_t         uFamily;
-    /** The CPU model. */
-    uint8_t         uModel;
-    /** The CPU stepping. */
-    uint8_t         uStepping;
-    /** The microarchitecture. */
-#ifndef VBOX_FOR_DTRACE_LIB
-    CPUMMICROARCH   enmMicroarch;
-#else
-    uint32_t        enmMicroarch;
-#endif
-    /** The maximum physical address with of the CPU. */
-    uint8_t         cMaxPhysAddrWidth;
-    /** Alignment padding. */
-    uint8_t         abPadding[1];
-    /** Max size of the extended state (or FPU state if no XSAVE). */
-    uint16_t        cbMaxExtendedState;
-
-    /** Supports MSRs. */
-    uint32_t        fMsr : 1;
-    /** Supports the page size extension (4/2 MB pages). */
-    uint32_t        fPse : 1;
-    /** Supports 36-bit page size extension (4 MB pages can map memory above
-     *  4GB). */
-    uint32_t        fPse36 : 1;
-    /** Supports physical address extension (PAE). */
-    uint32_t        fPae : 1;
-    /** Page attribute table (PAT) support (page level cache control). */
-    uint32_t        fPat : 1;
-    /** Supports the FXSAVE and FXRSTOR instructions. */
-    uint32_t        fFxSaveRstor : 1;
-    /** Supports the XSAVE and XRSTOR instructions. */
-    uint32_t        fXSaveRstor : 1;
-    /** Supports MMX. */
-    uint32_t        fMmx : 1;
-    /** Supports SSE. */
-    uint32_t        fSse : 1;
-    /** Supports SSE2. */
-    uint32_t        fSse2 : 1;
-    /** Supports SSE3. */
-    uint32_t        fSse3 : 1;
-    /** Supports SSSE3. */
-    uint32_t        fSsse3 : 1;
-    /** Supports SSE4.1. */
-    uint32_t        fSse41 : 1;
-    /** Supports SSE4.2. */
-    uint32_t        fSse42 : 1;
-    /** Supports AVX. */
-    uint32_t        fAvx : 1;
-    /** Supports AVX2. */
-    uint32_t        fAvx2 : 1;
-    /** Supports AVX512 foundation. */
-    uint32_t        fAvx512Foundation : 1;
-    /** Supports RDTSC. */
-    uint32_t        fTsc : 1;
-    /** Intel SYSENTER/SYSEXIT support */
-    uint32_t        fSysEnter : 1;
-    /** First generation APIC. */
-    uint32_t        fApic : 1;
-    /** Second generation APIC. */
-    uint32_t        fX2Apic : 1;
-    /** Hypervisor present. */
-    uint32_t        fHypervisorPresent : 1;
-    /** MWAIT & MONITOR instructions supported. */
-    uint32_t        fMonitorMWait : 1;
-    /** MWAIT Extensions present. */
-    uint32_t        fMWaitExtensions : 1;
-
-    /** AMD64: Supports long mode. */
-    uint32_t        fLongMode : 1;
-    /** AMD64: SYSCALL/SYSRET support. */
-    uint32_t        fSysCall : 1;
-    /** AMD64: No-execute page table bit. */
-    uint32_t        fNoExecute : 1;
-    /** AMD64: Supports LAHF & SAHF instructions in 64-bit mode. */
-    uint32_t        fLahfSahf : 1;
-    /** AMD64: Supports RDTSCP. */
-    uint32_t        fRdTscP : 1;
-
-    /** Indicates that FPU instruction and data pointers may leak.
-     * This generally applies to recent AMD CPUs, where the FPU IP and DP pointer
-     * is only saved and restored if an exception is pending. */
-    uint32_t        fLeakyFxSR : 1;
-
-    /** Alignment padding / reserved for future use. */
-    uint32_t        fPadding : 2;
-    uint64_t        auPadding[2];
-} CPUMFEATURES;
-#ifndef VBOX_FOR_DTRACE_LIB
-AssertCompileSize(CPUMFEATURES, 32);
-#endif
-/** Pointer to a CPU feature structure. */
-typedef CPUMFEATURES *PCPUMFEATURES;
-/** Pointer to a const CPU feature structure. */
-typedef CPUMFEATURES const *PCCPUMFEATURES;
-
-
 /**
  * CPU info
  */
@@ -409,7 +302,7 @@ typedef struct CPUMHOSTCTX
     /** @} */
 
     /* padding to get 64byte aligned size */
-    uint8_t         auPadding[16+20];
+    uint8_t         auPadding[20];
 
 #elif HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
 
@@ -455,9 +348,9 @@ typedef struct CPUMHOSTCTX
 
     /* padding to get 32byte aligned size */
 # ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    uint8_t         auPadding[4];
+    uint8_t         auPadding[52];
 # else
-    uint8_t         auPadding[8+12];
+    uint8_t         auPadding[4];
 # endif
 
 #else
@@ -470,6 +363,11 @@ typedef struct CPUMHOSTCTX
     R0PTRTYPE(PX86XSAVEAREA)    pXStateR0;
     /** Pointer to the FPU/SSE/AVX/XXXX state ring-3 mapping. */
     R3PTRTYPE(PX86XSAVEAREA)    pXStateR3;
+    /** The XCR0 register. */
+    uint64_t                    xcr0;
+    /** The mask to pass to XSAVE/XRSTOR in EDX:EAX.  If zero we use
+     *  FXSAVE/FXRSTOR (since bit 0 will always be set, we only need to test it). */
+    uint64_t                    fXStateMask;
 } CPUMHOSTCTX;
 AssertCompileSizeAlignment(CPUMHOSTCTX, 64);
 /** Pointer to the saved host CPU state. */
@@ -501,7 +399,24 @@ typedef struct CPUM
     /** Indicates that a state restore is pending.
      * This is used to verify load order dependencies (PGM). */
     bool                    fPendingRestore;
-    uint8_t                 abPadding[HC_ARCH_BITS == 64 ? 6 : 2];
+    uint8_t                 abPadding0[6];
+
+    /** XSAVE/XRTOR components we can expose to the guest mask. */
+    uint64_t                fXStateGuestMask;
+    /** XSAVE/XRSTOR host mask.  Only state components in this mask can be exposed
+     * to the guest.  This is 0 if no XSAVE/XRSTOR bits can be exposed. */
+    uint64_t                fXStateHostMask;
+    uint8_t                 abPadding1[24];
+
+    /** Host CPU feature information.
+     * Externaly visible via the VM structure, aligned on 64-byte boundrary. */
+    CPUMFEATURES            HostFeatures;
+    /** Guest CPU feature information.
+     * Externaly visible via that VM structure, aligned with HostFeatures. */
+    CPUMFEATURES            GuestFeatures;
+    /** Guest CPU info. */
+    CPUMINFO                GuestInfo;
+
 
     /** The standard set of CpuId leaves. */
     CPUMCPUID               aGuestCpuIdPatmStd[6];
@@ -510,17 +425,6 @@ typedef struct CPUM
     /** The centaur set of CpuId leaves. */
     CPUMCPUID               aGuestCpuIdPatmCentaur[4];
 
-#if HC_ARCH_BITS == 32
-    uint8_t                 abPadding2[4];
-#endif
-
-    /** Guest CPU info. */
-    CPUMINFO                GuestInfo;
-    /** Guest CPU feature information. */
-    CPUMFEATURES            GuestFeatures;
-    /** Host CPU feature information. */
-    CPUMFEATURES            HostFeatures;
-
     /** @name MSR statistics.
      * @{ */
     STAMCOUNTER             cMsrWrites;
@@ -532,6 +436,8 @@ typedef struct CPUM
     STAMCOUNTER             cMsrReadsUnknown;
     /** @} */
 } CPUM;
+AssertCompileMemberOffset(CPUM, HostFeatures, 64);
+AssertCompileMemberOffset(CPUM, GuestFeatures, 96);
 /** Pointer to the CPUM instance data residing in the shared VM structure. */
 typedef CPUM *PCPUM;
 
diff --git a/src/VBox/VMM/include/CPUMInternal.mac b/src/VBox/VMM/include/CPUMInternal.mac
index 582eb78..56950ed 100644
--- a/src/VBox/VMM/include/CPUMInternal.mac
+++ b/src/VBox/VMM/include/CPUMInternal.mac
@@ -75,41 +75,38 @@ endstruc
 
 struc CPUM
     ;...
-    .offCPUMCPU0          resd    1
-    .fHostUseFlags        resd    1
+    .offCPUMCPU0                resd    1
+    .fHostUseFlags              resd    1
 
     ; CR4 masks
-    .CR4.AndMask          resd    1
-    .CR4.OrMask           resd    1
+    .CR4.AndMask                resd    1
+    .CR4.OrMask                 resd    1
     ; entered rawmode?
-    .u8PortableCpuIdLevel resb    1
-    .fPendingRestore      resb    1
-%if RTHCPTR_CB == 8
-    .abPadding            resb    6
-%else
-    .abPadding            resb    2
-%endif
+    .u8PortableCpuIdLevel       resb    1
+    .fPendingRestore            resb    1
+
+    alignb 8
+    .fXStateGuestMask           resq    1
+    .fXStateHostMask            resq    1
+
+    alignb 64
+    .HostFeatures               resb    32
+    .GuestFeatures              resb    32
+    .GuestInfo                  resb    RTHCPTR_CB*4 + RTRCPTR_CB*2 + 4*12
 
     ; Patch manager saved state compatability CPUID leaf arrays
     .aGuestCpuIdPatmStd         resb    16*6
     .aGuestCpuIdPatmExt         resb    16*10
     .aGuestCpuIdPatmCentaur     resb    16*4
 
-%if HC_ARCH_BITS == 32
-    .abPadding2           resb    4
-%endif
-
-    .GuestInfo            resb    RTHCPTR_CB*4 + RTRCPTR_CB*2 + 4*12
-    .GuestFeatures        resb    32
-    .HostFeatures         resb    32
-
-    .cMsrWrites                 resq  1
-    .cMsrWritesToIgnoredBits    resq  1
-    .cMsrWritesRaiseGp          resq  1
-    .cMsrWritesUnknown          resq  1
-    .cMsrReads                  resq  1
-    .cMsrReadsRaiseGp           resq  1
-    .cMsrReadsUnknown           resq  1
+    alignb 8
+    .cMsrWrites                 resq    1
+    .cMsrWritesToIgnoredBits    resq    1
+    .cMsrWritesRaiseGp          resq    1
+    .cMsrWritesUnknown          resq    1
+    .cMsrReads                  resq    1
+    .cMsrReadsRaiseGp           resq    1
+    .cMsrReadsUnknown           resq    1
 endstruc
 
 struc CPUMCPU
@@ -216,9 +213,12 @@ struc CPUMCPU
     .Guest.msrSFMASK          resb    8
     .Guest.msrKERNELGSBASE    resb    8
     .Guest.msrApicBase        resb    8
-    .Guest.pXStateR0          RTR0PTR_RES 1
-    .Guest.pXStateR3          RTR3PTR_RES 1
-    .Guest.pXStateRC          RTRCPTR_RES 1
+    .Guest.aXcr               resq    2
+    .Guest.fXStateMask        resq    1
+    .Guest.pXStateR0      RTR0PTR_RES 1
+    .Guest.pXStateR3      RTR3PTR_RES 1
+    .Guest.pXStateRC      RTRCPTR_RES 1
+    .Guest.aoffXState         resw    64
 
     alignb 64
     .GuestMsrs                resq    0
@@ -323,7 +323,7 @@ struc CPUMCPU
     .Host.SysEnter.eip   resq    1
     .Host.SysEnter.esp   resq    1
     .Host.efer           resq    1
-    .Host.auPadding      resb    (16+20)
+    .Host.auPadding      resb    (20)
 
 %else ; 64-bit
 
@@ -356,15 +356,18 @@ struc CPUMCPU
     .Host.GSbase         resq    1
     .Host.efer           resq    1
  %if fVBOX_WITH_HYBRID_32BIT_KERNEL
-    .Host.auPadding      resb    4
+    .Host.auPadding      resb    54
  %else
-    .Host.auPadding      resb   (8+12)
+    .Host.auPadding      resb    4
  %endif
 %endif ; 64-bit
     .Host.pXStateRC RTRCPTR_RES  1
     alignb RTR0PTR_CB
     .Host.pXStateR0 RTR0PTR_RES  1
     .Host.pXStateR3 RTR3PTR_RES  1
+    alignb 8
+    .Host.xcr0           resq    1
+    .Host.fXStateMask    resq    1
 
     ;
     ; Hypervisor Context (same as .Guest above).
@@ -469,9 +472,12 @@ struc CPUMCPU
     .Hyper.msrSFMASK          resb    8
     .Hyper.msrKERNELGSBASE    resb    8
     .Hyper.msrApicBase        resb    8
-    .Hyper.pXStateR0          RTR0PTR_RES 1
-    .Hyper.pXStateR3          RTR3PTR_RES 1
-    .Hyper.pXStateRC          RTRCPTR_RES 1
+    .Hyper.aXcr               resq    2
+    .Hyper.fXStateMask        resq    1
+    .Hyper.pXStateR0      RTR0PTR_RES 1
+    .Hyper.pXStateR3      RTR3PTR_RES 1
+    .Hyper.pXStateRC      RTRCPTR_RES 1
+    .Hyper.aoffXState         resw    64
     alignb 64
 
 %ifdef VBOX_WITH_CRASHDUMP_MAGIC
diff --git a/src/VBox/VMM/include/GIMKvmInternal.h b/src/VBox/VMM/include/GIMKvmInternal.h
index bbc6c41..608ddf1 100644
--- a/src/VBox/VMM/include/GIMKvmInternal.h
+++ b/src/VBox/VMM/include/GIMKvmInternal.h
@@ -192,18 +192,16 @@ AssertCompileSize(GIMKVMWALLCLOCK, 12);
  */
 typedef struct GIMKVM
 {
-    /** @name MSRs. */
     /** Wall-clock MSR. */
     uint64_t                    u64WallClockMsr;
-    /** @} */
 
-    /** @name CPUID features. */
-    /** Basic features. */
+    /**  CPUID features: Basic. */
     uint32_t                    uBaseFeat;
-    /** @} */
 
-    /** Whether we need to trap #UD exceptions. */
+    /** Whether GIM needs to trap #UD exceptions. */
     bool                        fTrapXcptUD;
+    /** Disassembler opcode of hypercall instruction native for this host CPU. */
+    uint16_t                    uOpCodeNative;
 } GIMKVM;
 /** Pointer to per-VM GIM KVM instance data. */
 typedef GIMKVM *PGIMKVM;
@@ -262,8 +260,8 @@ VMM_INT_DECL(bool)              gimKvmAreHypercallsEnabled(PVMCPU pVCpu);
 VMM_INT_DECL(int)               gimKvmHypercall(PVMCPU pVCpu, PCPUMCTX pCtx);
 VMM_INT_DECL(VBOXSTRICTRC)      gimKvmReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue);
 VMM_INT_DECL(VBOXSTRICTRC)      gimKvmWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue);
-VMM_INT_DECL(bool)              gimKvmShouldTrapXcptUD(PVM pVM);
-VMM_INT_DECL(int)               gimKvmXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx);
+VMM_INT_DECL(bool)              gimKvmShouldTrapXcptUD(PVMCPU pVCpu);
+VMM_INT_DECL(int)               gimKvmXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis);
 
 
 RT_C_DECLS_END
diff --git a/src/VBox/VMM/include/HMInternal.h b/src/VBox/VMM/include/HMInternal.h
index 4f30804..4d30d5b 100644
--- a/src/VBox/VMM/include/HMInternal.h
+++ b/src/VBox/VMM/include/HMInternal.h
@@ -163,18 +163,19 @@ RT_C_DECLS_BEGIN
 #define HM_CHANGED_GUEST_SYSENTER_ESP_MSR        RT_BIT(15)
 #define HM_CHANGED_GUEST_EFER_MSR                RT_BIT(16)
 #define HM_CHANGED_GUEST_LAZY_MSRS               RT_BIT(17)     /* Shared */
+#define HM_CHANGED_GUEST_XCPT_INTERCEPTS         RT_BIT(18)
 /* VT-x specific state. */
-#define HM_CHANGED_VMX_GUEST_AUTO_MSRS           RT_BIT(18)
-#define HM_CHANGED_VMX_GUEST_ACTIVITY_STATE      RT_BIT(19)
-#define HM_CHANGED_VMX_GUEST_APIC_STATE          RT_BIT(20)
-#define HM_CHANGED_VMX_ENTRY_CTLS                RT_BIT(21)
-#define HM_CHANGED_VMX_EXIT_CTLS                 RT_BIT(22)
+#define HM_CHANGED_VMX_GUEST_AUTO_MSRS           RT_BIT(19)
+#define HM_CHANGED_VMX_GUEST_ACTIVITY_STATE      RT_BIT(20)
+#define HM_CHANGED_VMX_GUEST_APIC_STATE          RT_BIT(21)
+#define HM_CHANGED_VMX_ENTRY_CTLS                RT_BIT(22)
+#define HM_CHANGED_VMX_EXIT_CTLS                 RT_BIT(23)
 /* AMD-V specific state. */
-#define HM_CHANGED_SVM_GUEST_APIC_STATE          RT_BIT(18)
-#define HM_CHANGED_SVM_RESERVED1                 RT_BIT(19)
-#define HM_CHANGED_SVM_RESERVED2                 RT_BIT(20)
-#define HM_CHANGED_SVM_RESERVED3                 RT_BIT(21)
-#define HM_CHANGED_SVM_RESERVED4                 RT_BIT(22)
+#define HM_CHANGED_SVM_GUEST_APIC_STATE          RT_BIT(19)
+#define HM_CHANGED_SVM_RESERVED1                 RT_BIT(20)
+#define HM_CHANGED_SVM_RESERVED2                 RT_BIT(21)
+#define HM_CHANGED_SVM_RESERVED3                 RT_BIT(22)
+#define HM_CHANGED_SVM_RESERVED4                 RT_BIT(23)
 
 #define HM_CHANGED_ALL_GUEST                     (  HM_CHANGED_GUEST_CR0                \
                                                   | HM_CHANGED_GUEST_CR3                \
@@ -194,13 +195,14 @@ RT_C_DECLS_BEGIN
                                                   | HM_CHANGED_GUEST_SYSENTER_ESP_MSR   \
                                                   | HM_CHANGED_GUEST_EFER_MSR           \
                                                   | HM_CHANGED_GUEST_LAZY_MSRS          \
+                                                  | HM_CHANGED_GUEST_XCPT_INTERCEPTS    \
                                                   | HM_CHANGED_VMX_GUEST_AUTO_MSRS      \
                                                   | HM_CHANGED_VMX_GUEST_ACTIVITY_STATE \
                                                   | HM_CHANGED_VMX_GUEST_APIC_STATE     \
                                                   | HM_CHANGED_VMX_ENTRY_CTLS           \
                                                   | HM_CHANGED_VMX_EXIT_CTLS)
 
-#define HM_CHANGED_HOST_CONTEXT                  RT_BIT(23)
+#define HM_CHANGED_HOST_CONTEXT                  RT_BIT(24)
 
 /* Bits shared between host and guest. */
 #define HM_CHANGED_HOST_GUEST_SHARED_STATE       (  HM_CHANGED_GUEST_CR0                \
@@ -342,9 +344,7 @@ typedef struct HM
     bool                        fGlobalInit;
     /** Set when TPR patching is active. */
     bool                        fTPRPatchingActive;
-    /** Whether #UD needs to be intercepted (required by certain GIM providers). */
-    bool                        fTrapXcptUD;
-    bool                        u8Alignment[2];
+    bool                        u8Alignment[3];
 
     /** Host kernel flags that HM might need to know (SUPKERNELFEATURES_XXX). */
     uint32_t                    uHostKernelFeatures;
@@ -582,6 +582,12 @@ typedef struct HMCPU
     /** Whether to preload the guest-FPU state to avoid #NM VM-exit overhead. */
     bool                        fPreloadGuestFpu;
 
+    /** Whether #UD needs to be intercepted (required by certain GIM providers). */
+    bool                        fGIMTrapXcptUD;
+    /** Whether paravirt. hypercalls are enabled. */
+    bool                        fHypercallsEnabled;
+    uint8_t                     u8Alignment0[6];
+
     /** World switch exit counter. */
     volatile uint32_t           cWorldSwitchExits;
     /** HM_CHANGED_* flags. */
diff --git a/src/VBox/VMM/include/IEMInternal.h b/src/VBox/VMM/include/IEMInternal.h
index e659a8c..5b6a708 100644
--- a/src/VBox/VMM/include/IEMInternal.h
+++ b/src/VBox/VMM/include/IEMInternal.h
@@ -372,22 +372,12 @@ typedef struct IEMCPU
 
     /** @name Target CPU information.
      * @{ */
-    /** EDX value of CPUID(1).
-     * @remarks Some bits are subject to change and must be queried dynamically. */
-    uint32_t                fCpuIdStdFeaturesEdx;
-    /** ECX value of CPUID(1).
-     * @remarks Some bits are subject to change and must be queried dynamically. */
-    uint32_t                fCpuIdStdFeaturesEcx;
     /** The CPU vendor. */
     CPUMCPUVENDOR           enmCpuVendor;
     /** @} */
 
     /** @name Host CPU information.
      * @{ */
-    /** EDX value of CPUID(1). */
-    uint32_t                fHostCpuIdStdFeaturesEdx;
-    /** ECX value of CPUID(1). */
-    uint32_t                fHostCpuIdStdFeaturesEcx;
     /** The CPU vendor. */
     CPUMCPUVENDOR           enmHostCpuVendor;
     /** @} */
diff --git a/src/VBox/VMM/testcase/tstIEMCheckMc.cpp b/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
index 57c1725..1c80fa5 100644
--- a/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
+++ b/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
@@ -137,14 +137,10 @@ typedef VBOXSTRICTRC (* PFNIEMOP)(PIEMCPU pIemCpu);
 #define IEM_IS_REAL_OR_V86_MODE(a_pIemCpu)                  (g_fRandom)
 #define IEM_IS_LONG_MODE(a_pIemCpu)                         (g_fRandom)
 #define IEM_IS_REAL_MODE(a_pIemCpu)                         (g_fRandom)
-#define IEM_IS_AMD_CPUID_FEATURE_PRESENT_ECX(a_fEcx)        (g_fRandom)
-#define IEM_IS_AMD_CPUID_FEATURE_PRESENT_EDX(a_fEdx)        (g_fRandom)
-#define IEM_IS_AMD_CPUID_FEATURES_ANY_PRESENT(a_fEdx, a_fEcx) (g_fRandom)
-#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(a_fEdx)      (g_fRandom)
-#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(a_fEcx)      (g_fRandom)
-#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(a_fEdx) (g_fRandom)
 #define IEM_IS_GUEST_CPU_AMD(a_pIemCpu)                     (g_fRandom)
 #define IEM_IS_GUEST_CPU_INTEL(a_pIemCpu)                   (g_fRandom)
+#define IEM_GET_GUEST_CPU_FEATURES(a_pIemCpu)               ((PCCPUMFEATURES)(uintptr_t)42)
+#define IEM_GET_HOST_CPU_FEATURES(a_pIemCpu)                ((PCCPUMFEATURES)(uintptr_t)88)
 
 #define iemRecalEffOpSize(a_pIemCpu)                        do { } while (0)
 
diff --git a/src/VBox/VMM/testcase/tstX86-FpuSaveRestoreA.asm b/src/VBox/VMM/testcase/tstX86-FpuSaveRestoreA.asm
index 8b199d3..3680553 100644
--- a/src/VBox/VMM/testcase/tstX86-FpuSaveRestoreA.asm
+++ b/src/VBox/VMM/testcase/tstX86-FpuSaveRestoreA.asm
@@ -61,7 +61,7 @@ BEGINPROC MyFpuSave
         mov         ecx, [esp + 4]
         fxsave      [ecx]
 %else
- %error "Unsupported architecture.
+ %error "Unsupported architecture."
         bad arch
 %endif
         ret
@@ -77,7 +77,7 @@ BEGINPROC MyFpuStoreEnv
         mov     ecx, [esp + 4]
         fstenv  [ecx]
 %else
- %error "Unsupported architecture.
+ %error "Unsupported architecture."
         bad arch
 %endif
         ret
@@ -93,7 +93,7 @@ BEGINPROC MyFpuRestore
         mov         ecx, [esp + 4]
         fxrstor     [ecx]
 %else
- %error "Unsupported architecture.
+ %error "Unsupported architecture."
         bad arch
 %endif
         ret
@@ -109,7 +109,7 @@ BEGINPROC MyFpuLoadEnv
         mov     ecx, [esp + 4]
         fldenv  [ecx]
 %else
- %error "Unsupported architecture.
+ %error "Unsupported architecture."
         bad arch
 %endif
         ret
diff --git a/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac b/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac
index 372f5cc..2b1d7da 100644
--- a/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac
+++ b/src/VBox/ValidationKit/bootsectors/bootsector2-first.mac
@@ -28,7 +28,7 @@
 %define ___bootsector2_first_mac
 
 ;
-; Undefine thing that shouldn't be defined if we're targetting the
+; Undefine thing that shouldn't be defined if we're targeting the
 ; binary format directly. These macros comes from DEFS in Config.kmk.
 ;
 %ifdef ASM_FORMAT_BIN
diff --git a/src/VBox/ValidationKit/common/__init__.py b/src/VBox/ValidationKit/common/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/constants/__init__.py b/src/VBox/ValidationKit/common/constants/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/constants/result.py b/src/VBox/ValidationKit/common/constants/result.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/constants/rtexitcode.py b/src/VBox/ValidationKit/common/constants/rtexitcode.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/constants/tbreq.py b/src/VBox/ValidationKit/common/constants/tbreq.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/constants/tbresp.py b/src/VBox/ValidationKit/common/constants/tbresp.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/constants/valueunit.py b/src/VBox/ValidationKit/common/constants/valueunit.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/utils.py b/src/VBox/ValidationKit/common/utils.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/common/webutils.py b/src/VBox/ValidationKit/common/webutils.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testanalysis/__init__.py b/src/VBox/ValidationKit/testanalysis/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testanalysis/diff.py b/src/VBox/ValidationKit/testanalysis/diff.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testboxscript/setup.sh b/src/VBox/ValidationKit/testboxscript/setup.sh
old mode 100755
new mode 100644
diff --git a/src/VBox/ValidationKit/testboxscript/testboxcommand.py b/src/VBox/ValidationKit/testboxscript/testboxcommand.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testboxscript/testboxcommons.py b/src/VBox/ValidationKit/testboxscript/testboxcommons.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testboxscript/testboxconnection.py b/src/VBox/ValidationKit/testboxscript/testboxconnection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testboxscript/testboxtasks.py b/src/VBox/ValidationKit/testboxscript/testboxtasks.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testboxscript/testboxupgrade.py b/src/VBox/ValidationKit/testboxscript/testboxupgrade.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testdriver/__init__.py b/src/VBox/ValidationKit/testdriver/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testdriver/base.py b/src/VBox/ValidationKit/testdriver/base.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testdriver/reporter.py b/src/VBox/ValidationKit/testdriver/reporter.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testdriver/tst-txsclient.py b/src/VBox/ValidationKit/testdriver/tst-txsclient.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testdriver/txsclient.py b/src/VBox/ValidationKit/testdriver/txsclient.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testdriver/vbox.py b/src/VBox/ValidationKit/testdriver/vbox.py
old mode 100644
new mode 100755
index 2267772..442837d
--- a/src/VBox/ValidationKit/testdriver/vbox.py
+++ b/src/VBox/ValidationKit/testdriver/vbox.py
@@ -27,7 +27,7 @@ CDDL are applicable instead of those of the GPL.
 You may elect to license modified versions of this file under the
 terms and conditions of either the GPL or the CDDL or both.
 """
-__version__ = "$Revision: 98764 $"
+__version__ = "$Revision: 99374 $"
 
 
 # Standard Python imports.
@@ -1245,8 +1245,8 @@ class TestDriver(base.TestDriver):
             except:
                 reporter.logXcpt('Failed to get VirtualBox version, assuming 4.0.0');
                 sVer = "4.0.0";
-            if sVer.startswith("4.4") or (sVer.startswith("4.3.5") and len(sVer) == 6):
-                self.fpApiVer = 4.4;
+            if sVer.startswith("5.0") or (sVer.startswith("4.3.5") and len(sVer) == 6):
+                self.fpApiVer = 5.0;
             elif sVer.startswith("4.3") or (sVer.startswith("4.2.5") and len(sVer) == 6):
                 self.fpApiVer = 4.3;
             elif sVer.startswith("4.2."):
diff --git a/src/VBox/ValidationKit/testdriver/vboxtestvms.py b/src/VBox/ValidationKit/testdriver/vboxtestvms.py
old mode 100644
new mode 100755
index 42b79fa..2f46a95
--- a/src/VBox/ValidationKit/testdriver/vboxtestvms.py
+++ b/src/VBox/ValidationKit/testdriver/vboxtestvms.py
@@ -26,7 +26,7 @@ CDDL are applicable instead of those of the GPL.
 You may elect to license modified versions of this file under the
 terms and conditions of either the GPL or the CDDL or both.
 """
-__version__ = "$Revision: 99297 $"
+__version__ = "$Revision: 99376 $"
 
 # Standard Python imports.
 import re;
@@ -316,7 +316,7 @@ class TestVm(object):
                         fRc = fRc and oSession.enableNestedPaging(sVirtMode == 'hwvirt-np');
                         fRc = fRc and oSession.setCpuCount(cCpus);
 
-                        if sParavirtMode is not None and oSession.fpApiVer >= 4.4:
+                        if sParavirtMode is not None and oSession.fpApiVer >= 5.0:
                             adParavirtProviders = {
                                 g_ksParavirtProviderNone   : vboxcon.ParavirtProvider_None,
                                 g_ksParavirtProviderDefault: vboxcon.ParavirtProvider_Default,
@@ -707,10 +707,10 @@ class TestVmSet(object):
             acCpusSup      = [cCpus for cCpus in oTestVm.acCpusSup      if cCpus in self.acCpus];
 
             # Ditto for paravirtualization modes, except if not specified we got a less obvious default.
-            if self.asParavirtModes is not None  and  oTestDrv.fpApiVer >= 4.4:
+            if self.asParavirtModes is not None  and  oTestDrv.fpApiVer >= 5.0:
                 asParavirtModes = [sPvMode for sPvMode in oTestVm.asParavirtModesSup if sPvMode in self.asParavirtModes];
                 assert None not in asParavirtModes;
-            elif oTestDrv.fpApiVer >= 4.4:
+            elif oTestDrv.fpApiVer >= 5.0:
                 asParavirtModes = (oTestVm.asParavirtModesSup[0],);
                 assert asParavirtModes[0] is not None;
             else:
@@ -734,7 +734,7 @@ class TestVmSet(object):
 
                     for sParavirtMode in asParavirtModes:
                         if sParavirtMode is not None:
-                            assert oTestDrv.fpApiVer >= 4.4;
+                            assert oTestDrv.fpApiVer >= 5.0;
                             reporter.testStart('%s' % ( sParavirtMode, ) );
 
                         # Reconfigure the VM.
diff --git a/src/VBox/ValidationKit/testdriver/vboxwrappers.py b/src/VBox/ValidationKit/testdriver/vboxwrappers.py
old mode 100644
new mode 100755
index 821696d..7e9b8b1
--- a/src/VBox/ValidationKit/testdriver/vboxwrappers.py
+++ b/src/VBox/ValidationKit/testdriver/vboxwrappers.py
@@ -27,7 +27,7 @@ CDDL are applicable instead of those of the GPL.
 You may elect to license modified versions of this file under the
 terms and conditions of either the GPL or the CDDL or both.
 """
-__version__ = "$Revision: 99186 $"
+__version__ = "$Revision: 99521 $"
 
 
 # Standard Python imports.
@@ -1711,7 +1711,7 @@ class SessionWrapper(TdTaskBase):
         Returns Medium object on success and None on failure.  Error information is logged.
         """
         try:
-            if self.fpApiVer >= 4.4:
+            if self.fpApiVer >= 5.0:
                 oHd = self.oVBox.createMedium(sFmt, sHd, vboxcon.AccessMode_ReadWrite, vboxcon.DeviceType_HardDisk);
             else:
                 oHd = self.oVBox.createHardDisk(sFmt, sHd);
@@ -1731,7 +1731,7 @@ class SessionWrapper(TdTaskBase):
         Returns Medium object on success and None on failure.  Error information is logged.
         """
         try:
-            if self.fpApiVer >= 4.4:
+            if self.fpApiVer >= 5.0:
                 oHd = self.oVBox.createMedium(sFmt, sHd, vboxcon.AccessMode_ReadWrite, vboxcon.DeviceType_HardDisk);
             else:
                 oHd = self.oVBox.createHardDisk(sFmt, sHd);
@@ -2189,13 +2189,16 @@ class SessionWrapper(TdTaskBase):
         Restores the given snapshot.
 
         Returns True on success.
-        Returns False on IConsole::restoreSnapshot() failure.
+        Returns False on IMachine::restoreSnapshot() failure.
         Returns None if the progress object returns failure.
         """
         try:
-            oProgress = self.o.console.restoreSnapshot(oSnapshot);
+            if self.fpApiVer >= 5.0:
+                oProgress = self.o.machine.restoreSnapshot(oSnapshot);
+            else:
+                oProgress = self.o.console.restoreSnapshot(oSnapshot);
         except:
-            reporter.logXcpt('IConsole::restoreSnapshot failed on %s' % (self.sName));
+            reporter.logXcpt('IMachine::restoreSnapshot failed on %s' % (self.sName));
             if fFudgeOnFailure:
                 self.oTstDrv.waitOnDirectSessionClose(self.oVM, 5000); # fudge
                 self.waitForTask(1000);                                # fudge
@@ -2215,15 +2218,18 @@ class SessionWrapper(TdTaskBase):
         Deletes the given snapshot merging the diff image into the base.
 
         Returns True on success.
-        Returns False on IConsole::deleteSnapshot() failure.
+        Returns False on IMachine::deleteSnapshot() failure.
         """
         try:
-            oProgressCom = self.o.console.deleteSnapshot(oSnapshot);
+            if self.fpApiVer >= 5.0:
+                oProgressCom = self.o.machine.deleteSnapshot(oSnapshot);
+            else:
+                oProgressCom = self.o.console.deleteSnapshot(oSnapshot);
             oProgress = ProgressWrapper(oProgressCom, self.oVBoxMgr, self.oTstDrv, 'Delete Snapshot %s' % (oSnapshot));
             oProgress.wait(cMsTimeout);
             oProgress.logResult();
         except:
-            reporter.logXcpt('IConsole::deleteSnapshot failed on %s' % (self.sName));
+            reporter.logXcpt('IMachine::deleteSnapshot failed on %s' % (self.sName));
             if fFudgeOnFailure:
                 self.oTstDrv.waitOnDirectSessionClose(self.oVM, 5000); # fudge
                 self.waitForTask(1000);                                # fudge
@@ -2236,19 +2242,21 @@ class SessionWrapper(TdTaskBase):
         Takes a snapshot with the given name
 
         Returns True on success.
-        Returns False on IConsole::takeSnapshot() or VM state change failure.
+        Returns False on IMachine::takeSnapshot() or VM state change failure.
         """
         try:
             if     fPause is True \
                and self.oVM.state is vboxcon.MachineState_Running:
                 self.o.console.pause();
-
-            oProgressCom = self.o.console.takeSnapshot(sName, sDescription);
+            if self.fpApiVer >= 5.0:
+                oProgressCom = self.o.machine.takeSnapshot(sName, sDescription);
+            else:
+                oProgressCom = self.o.console.takeSnapshot(sName, sDescription);
             oProgress = ProgressWrapper(oProgressCom, self.oVBoxMgr, self.oTstDrv, 'Take Snapshot %s' % (sName));
             oProgress.wait(cMsTimeout);
             oProgress.logResult();
         except:
-            reporter.logXcpt('IConsole::takeSnapshot failed on %s' % (self.sName));
+            reporter.logXcpt('IMachine::takeSnapshot failed on %s' % (self.sName));
             if fFudgeOnFailure:
                 self.oTstDrv.waitOnDirectSessionClose(self.oVM, 5000); # fudge
                 self.waitForTask(1000);                                # fudge
@@ -2277,7 +2285,7 @@ class SessionWrapper(TdTaskBase):
         Returns False on failure.
         """
         try:
-            if self.fpApiVer >= 4.4:
+            if self.fpApiVer >= 5.0:
                 iWidth, iHeight, _, _, _, _ = self.o.console.display.getScreenResolution(iScreenId)
                 aPngData = self.o.console.display.takeScreenShotToArray(iScreenId, iWidth, iHeight,
                                                                         vboxcon.BitmapFormat_PNG)
diff --git a/src/VBox/ValidationKit/testdriver/winbase.py b/src/VBox/ValidationKit/testdriver/winbase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/__init__.py b/src/VBox/ValidationKit/testmanager/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/config.py b/src/VBox/ValidationKit/testmanager/config.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/__init__.py b/src/VBox/ValidationKit/testmanager/core/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/base.py b/src/VBox/ValidationKit/testmanager/core/base.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/build.py b/src/VBox/ValidationKit/testmanager/core/build.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/buildblacklist.py b/src/VBox/ValidationKit/testmanager/core/buildblacklist.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/buildsource.py b/src/VBox/ValidationKit/testmanager/core/buildsource.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/coreconsts.py b/src/VBox/ValidationKit/testmanager/core/coreconsts.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/db.py b/src/VBox/ValidationKit/testmanager/core/db.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/dbobjcache.py b/src/VBox/ValidationKit/testmanager/core/dbobjcache.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/failurecategory.py b/src/VBox/ValidationKit/testmanager/core/failurecategory.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/failurereason.py b/src/VBox/ValidationKit/testmanager/core/failurereason.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/globalresource.py b/src/VBox/ValidationKit/testmanager/core/globalresource.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/report.py b/src/VBox/ValidationKit/testmanager/core/report.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/schedgroup.py b/src/VBox/ValidationKit/testmanager/core/schedgroup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/schedulerbase.py b/src/VBox/ValidationKit/testmanager/core/schedulerbase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/schedulerbeci.py b/src/VBox/ValidationKit/testmanager/core/schedulerbeci.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/systemlog.py b/src/VBox/ValidationKit/testmanager/core/systemlog.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testbox.py b/src/VBox/ValidationKit/testmanager/core/testbox.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testboxcontroller.py b/src/VBox/ValidationKit/testmanager/core/testboxcontroller.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testboxstatus.py b/src/VBox/ValidationKit/testmanager/core/testboxstatus.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testcase.py b/src/VBox/ValidationKit/testmanager/core/testcase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testcaseargs.py b/src/VBox/ValidationKit/testmanager/core/testcaseargs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testgroup.py b/src/VBox/ValidationKit/testmanager/core/testgroup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testresults.py b/src/VBox/ValidationKit/testmanager/core/testresults.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/testset.py b/src/VBox/ValidationKit/testmanager/core/testset.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/useraccount.py b/src/VBox/ValidationKit/testmanager/core/useraccount.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/vcsrevisions.py b/src/VBox/ValidationKit/testmanager/core/vcsrevisions.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/webservergluebase.py b/src/VBox/ValidationKit/testmanager/core/webservergluebase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/core/webservergluecgi.py b/src/VBox/ValidationKit/testmanager/core/webservergluecgi.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/debug/__init__.py b/src/VBox/ValidationKit/testmanager/debug/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/__init__.py b/src/VBox/ValidationKit/testmanager/webui/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadmin.py b/src/VBox/ValidationKit/testmanager/webui/wuiadmin.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminbuild.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminbuild.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildblacklist.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildblacklist.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildcategory.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildcategory.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildsource.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildsource.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminfailurereason.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminfailurereason.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminglobalrsrc.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminglobalrsrc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminschedgroup.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminschedgroup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminsystemlog.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminsystemlog.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadmintestbox.py b/src/VBox/ValidationKit/testmanager/webui/wuiadmintestbox.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadmintestcase.py b/src/VBox/ValidationKit/testmanager/webui/wuiadmintestcase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadmintestgroup.py b/src/VBox/ValidationKit/testmanager/webui/wuiadmintestgroup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuiadminuseraccount.py b/src/VBox/ValidationKit/testmanager/webui/wuiadminuseraccount.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuibase.py b/src/VBox/ValidationKit/testmanager/webui/wuibase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuicontentbase.py b/src/VBox/ValidationKit/testmanager/webui/wuicontentbase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuifailurecategory.py b/src/VBox/ValidationKit/testmanager/webui/wuifailurecategory.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuigraphwiz.py b/src/VBox/ValidationKit/testmanager/webui/wuigraphwiz.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuihlpform.py b/src/VBox/ValidationKit/testmanager/webui/wuihlpform.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphgooglechart.py b/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphgooglechart.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphmatplotlib.py b/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphmatplotlib.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphsimple.py b/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphsimple.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuilogviewer.py b/src/VBox/ValidationKit/testmanager/webui/wuilogviewer.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuimain.py b/src/VBox/ValidationKit/testmanager/webui/wuimain.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuireport.py b/src/VBox/ValidationKit/testmanager/webui/wuireport.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuitestresult.py b/src/VBox/ValidationKit/testmanager/webui/wuitestresult.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/testmanager/webui/wuivcshistory.py b/src/VBox/ValidationKit/testmanager/webui/wuivcshistory.py
old mode 100644
new mode 100755
diff --git a/src/VBox/ValidationKit/tests/storage/tdStorageBenchmark1.py b/src/VBox/ValidationKit/tests/storage/tdStorageBenchmark1.py
index aac8233..938cf4f 100755
--- a/src/VBox/ValidationKit/tests/storage/tdStorageBenchmark1.py
+++ b/src/VBox/ValidationKit/tests/storage/tdStorageBenchmark1.py
@@ -27,7 +27,7 @@ CDDL are applicable instead of those of the GPL.
 You may elect to license modified versions of this file under the
 terms and conditions of either the GPL or the CDDL or both.
 """
-__version__ = "$Revision: 98539 $"
+__version__ = "$Revision: 99376 $"
 
 
 # Standard Python imports.
@@ -480,7 +480,7 @@ class tdStorageBenchmark(vbox.TestDriver):
                 listNames.append('TargetName');
                 listNames.append('LUN');
 
-                if self.fpApiVer >= 4.4:
+                if self.fpApiVer >= 5.0:
                     oHd = oSession.oVBox.createMedium(sDiskFormat, sDiskPath, vboxcon.AccessMode_ReadWrite, \
                                                       vboxcon.DeviceType_HardDisk);
                 else:
diff --git a/src/VBox/ValidationKit/tests/storage/tdStorageStress1.py b/src/VBox/ValidationKit/tests/storage/tdStorageStress1.py
index 05c07fb..0e3fb09 100755
--- a/src/VBox/ValidationKit/tests/storage/tdStorageStress1.py
+++ b/src/VBox/ValidationKit/tests/storage/tdStorageStress1.py
@@ -353,7 +353,7 @@ class tdStorageStress(vbox.TestDriver):                                      # p
                 listNames.append('TargetName');
                 listNames.append('LUN');
 
-                if self.fpApiVer >= 4.4:
+                if self.fpApiVer >= 5.0:
                     oHd = oSession.oVBox.createMedium(sDiskFormat, sDiskPath1, vboxcon.AccessMode_ReadWrite, \
                                                       vboxcon.DeviceType_HardDisk);
                 else:
diff --git a/src/VBox/ValidationKit/utils/cpu/cidet-app.cpp b/src/VBox/ValidationKit/utils/cpu/cidet-app.cpp
index 548c674..9644027 100644
--- a/src/VBox/ValidationKit/utils/cpu/cidet-app.cpp
+++ b/src/VBox/ValidationKit/utils/cpu/cidet-app.cpp
@@ -1308,7 +1308,11 @@ int main(int argc, char **argv)
 # else
     g_AltStack.ss_size  = _128K;
 # endif
+#ifdef RT_OS_FREEBSD
+    g_AltStack.ss_sp    = (char *)RTMemPageAlloc(g_AltStack.ss_size);
+#else
     g_AltStack.ss_sp    = RTMemPageAlloc(g_AltStack.ss_size);
+#endif
     RTTESTI_CHECK_RET(g_AltStack.ss_sp != NULL, RTEXITCODE_FAILURE);
     RTTESTI_CHECK_RC_RET(sigaltstack(&g_AltStack, NULL), 0, RTEXITCODE_FAILURE);
 
diff --git a/src/libs/xpcom18a4/nsprpub/Makefile.in b/src/libs/xpcom18a4/nsprpub/Makefile.in
old mode 100755
new mode 100644
diff --git a/src/libs/xpcom18a4/nsprpub/config/config.mk b/src/libs/xpcom18a4/nsprpub/config/config.mk
old mode 100755
new mode 100644
diff --git a/src/libs/xpcom18a4/nsprpub/config/rules.mk b/src/libs/xpcom18a4/nsprpub/config/rules.mk
old mode 100755
new mode 100644
diff --git a/src/libs/xpcom18a4/python/client/__init__.py b/src/libs/xpcom18a4/python/client/__init__.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/file.py b/src/libs/xpcom18a4/python/file.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/primitives.py b/src/libs/xpcom18a4/python/primitives.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/__init__.py b/src/libs/xpcom18a4/python/server/__init__.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/enumerator.py b/src/libs/xpcom18a4/python/server/enumerator.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/factory.py b/src/libs/xpcom18a4/python/server/factory.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/loader.py b/src/libs/xpcom18a4/python/server/loader.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/module.py b/src/libs/xpcom18a4/python/server/module.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/policy.py b/src/libs/xpcom18a4/python/server/policy.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/pyxpcom_test_tools.py b/src/libs/xpcom18a4/python/test/pyxpcom_test_tools.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_com_exceptions.py b/src/libs/xpcom18a4/python/test/test_com_exceptions.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_comfile.py b/src/libs/xpcom18a4/python/test/test_comfile.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_component/py_test_component.py b/src/libs/xpcom18a4/python/test/test_component/py_test_component.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_components.py b/src/libs/xpcom18a4/python/test/test_components.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_isupports_primitives.py b/src/libs/xpcom18a4/python/test/test_isupports_primitives.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_misc.py b/src/libs/xpcom18a4/python/test/test_misc.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_streams.py b/src/libs/xpcom18a4/python/test/test_streams.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_test_component.py b/src/libs/xpcom18a4/python/test/test_test_component.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_weakreferences.py b/src/libs/xpcom18a4/python/test/test_weakreferences.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/tools/regxpcom.py b/src/libs/xpcom18a4/python/tools/regxpcom.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/xpt.py b/src/libs/xpcom18a4/python/xpt.py
old mode 100644
new mode 100755

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-virtualbox/virtualbox.git



More information about the Pkg-virtualbox-commits mailing list