(#11870) Refactor the MSI provider to use package options

Previously, the MSI provider contained logic for accepting a hash of
`install_options`. The provider's install method flattened the hash pairs
as:

    "key1=value1 key2=value2"

and passed that to msiexec.exe. This worked fine for MSI public
properties, but does not account for passing single arguments.

This commit refactors the provider to use the more generic version of
`install_options`, which expects an array of values. For example, if a
manifest contains:

    [ '/S', { 'INSTALLDIR' => 'C:\Program Files' } ]

then msiexec will be invoked with:

    "/S INSTALLDIR=\"C:\\Program Files\""

The only change in behavior is that the MSI provider will now accept
single arguments and pass those onto msiexec.
(#11870) Add the ability to specify uninstall_options

Previously, the MSI provider was unable to specify uninstall_options.
This isn't typically an issue, since Windows stores the command and
arguments necessary to uninstall the package in the `UninstallString`
registry value associated with the package.

But there are some MSI packages that require this functionality, e.g. to
specify VMware Tools modules to uninstall:

   msiexec.exe /x <productcode> REMOVE=Sync,VSS,...

This commit adds an `uninstall_options` parameter to the package type and
updates the MSI provider to use it. It has the same format as
`install_options`.
(#11870) Deprecate the `:msi` provider

The `:msi` package provider is being deprecated and replaced with the
`:windows` provider. Attempting to install or uninstall a package using
the msi provider will cause puppet to issue a deprecation warning.

The windows provider is basically a copy of the MSI provider, though it
will be capable of managing executable packages in a future commit.
(#11870) Refactor package management logic for MSI

This commit moves the logic for querying, installing and uninstalling MSI
packages into a MsiPackage class separate from the main windows package
provider. This is being done in preparation for adding executable package
support (as some of the logic is very similar), such as querying the
registry for installed products. Additionally, executable and MSI
packages can be related, which makes partitioning the set of installed
packages into different MSI and executable providers not really feasible.
(#11870) Manage executable packages on Windows

Previously, puppet could only manage MSI packages on Windows. This commit
extends the `:windows` package provider so that it can query, install, and
uninstall executable packages. The logic for this is borrowed from[1].

Basically, puppet will only manage executable packages that have the
following attributes:

    Non-empty DisplayName
    Non-empty UninstallString
    Are not SystemComponents
    Are not WindowsInstaller
    Names don't start with KBXXXXXX
    Are not part of another product (ParentKeyName)
    Are not Security Update, Update Rollup or Hotfix

For example, to install Java silently:

    package { 'Java(TM) 7 Update 5':
      ensure          => installed,
      source          => '...\jre-7u5-windows-i586.exe',
      install_options => [
        '/s', '/v/qn" ADDLOCAL=jrecore REBOOT=Suppress JAVAUPDATE=0"'
      ]
    }

[1] http://community.spiceworks.com/how_to/show/2238