text:
<#
    Suppress PSAvoidUsingConvertToSecureStringWithPlainText since SecureString
    objects are used for test passwords.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')]
param ()

$script:dscModuleName = 'xPSDesiredStateConfiguration'
$script:dscResourceName = 'DSC_xMsiPackage'

function Invoke-TestSetup
{
    try
    {
        Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop'
    }
    catch [System.IO.FileNotFoundException]
    {
        throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.'
    }

    $script:testEnvironment = Initialize-TestEnvironment `
        -DSCModuleName $script:dscModuleName `
        -DSCResourceName $script:dscResourceName `
        -ResourceType 'Mof' `
        -TestType 'Unit'

    Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\TestHelpers\CommonTestHelper.psm1')
}

function Invoke-TestCleanup
{
    Restore-TestEnvironment -TestEnvironment $script:testEnvironment
}

Invoke-TestSetup

# Begin Testing
try
{
    InModuleScope $script:dscResourceName {
        Describe 'xMsiPackage Unit Tests' {
            BeforeAll {
                $script:testUsername = 'TestUsername'
                $script:testPassword = 'TestPassword'
                $script:secureTestPassword = ConvertTo-SecureString -String $script:testPassword -AsPlainText -Force

                $script:testCredential = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList @( $script:testUsername, $script:secureTestPassword )
                $script:testProductId = '{deadbeef-80c6-41e6-a1b9-8bdb8a05027f}'
                $script:testIdentifyingNumber = '{DEADBEEF-80C6-41E6-A1B9-8BDB8A05027F}'
                $script:testWrongProductId = 'wrongId'
                $script:testPath = 'file://test.msi'
                $script:destinationPath = Join-Path -Path $script:packageCacheLocation -ChildPath (Get-Location).Drive.Root
                $script:testUriHttp = [System.Uri] 'http://test.msi'
                $script:testUriHttps = [System.Uri] 'https://test.msi'
                $script:testUriFile = [System.Uri] 'file://test.msi'
                $script:testUriNonUnc = [System.Uri] 'file:///C:/test.msi'
                $script:testUriQuery = [System.Uri] 'http://C:/directory/test/test.msi?sv=2017-01-31&spr=https'
                $script:testUriOnlyFile = [System.Uri] 'test.msi'

                $script:mockStream = New-MockObject -Type 'System.IO.FileStream'
                $script:mockWebRequest = New-MockObject -Type 'System.Net.HttpWebRequest'
                $script:mockStartInfo = New-MockObject -Type 'System.Diagnostics.ProcessStartInfo'
                $script:mockProcess = New-MockObject -Type 'System.Diagnostics.Process'
                $script:mockProductEntry = New-MockObject -Type 'Microsoft.Win32.RegistryKey'

                $script:mockPSDrive = @{
                    Root = 'mockRoot'
                }

                $script:mockProductEntryInfo = @{
                    Name               = 'TestDisplayName'
                    InstallSource      = 'TestInstallSource'
                    InstalledOn        = [System.DateTime] '4/4/2017'
                    Size               = 2048
                    Version            = '1.2.3.4'
                    PackageDescription = 'Test Description'
                    Publisher          = 'Test Publisher'
                    Ensure             = 'Present'
                }

                # Used to create the names of the tests that check to ensure the correct error is thrown.
                $script:errorMessageTitles = @{
                    CouldNotOpenLog      = 'not being able to open the log path'
                    InvalidId            = 'the specified product ID not matching the actual product ID'
                    CouldNotOpenDestFile = 'not being able to open the destination file to write to'
                    PathDoesNotExist     = 'not being able to find the path'
                    CouldNotStartProcess = 'not being able to start the process'
                    PostValidationError  = 'not being able to find the package after installation'
                }
            }

            Describe 'xMsiPackage\Get-TargetResource' {
                Mock -CommandName 'Convert-ProductIdToIdentifyingNumber' -MockWith { return $script:testIdentifyingNumber }
                Mock -CommandName 'Get-ProductEntry' -MockWith { return $null }
                Mock -CommandName 'Get-ProductEntryInfo' -MockWith { return $script:mockProductEntryInfo }

                Context 'When MSI package does not exist' {
                    $getTargetResourceParameters = @{
                        ProductId = $script:testProductId
                        Path      = $script:testPath
                    }

                    $mocksCalled = @(
                        @{
                            Command = 'Convert-ProductIdToIdentifyingNumber'
                            Times   = 1
                        }
                        @{
                            Command = 'Get-ProductEntry'
                            Times   = 1
                        }
                        @{
                            Command = 'Get-ProductEntryInfo'
                            Times   = 0
                        }
                    )

                    $expectedReturnValue = @{
                        Ensure    = 'Absent'
                        ProductId = $script:testIdentifyingNumber
                    }

                    Invoke-GetTargetResourceUnitTest -GetTargetResourceParameters $getTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ExpectedReturnValue $expectedReturnValue
                }

                Mock -CommandName 'Get-ProductEntry' -MockWith { return $script:mockProductEntry }

                Context 'When MSI package does exist' {
                    $getTargetResourceParameters = @{
                        ProductId = $script:testProductId
                        Path      = $script:testPath
                    }

                    $mocksCalled = @(
                        @{
                            Command = 'Convert-ProductIdToIdentifyingNumber'
                            Times   = 1
                        }
                        @{
                            Command = 'Get-ProductEntry'
                            Times   = 1
                        }
                        @{
                            Command = 'Get-ProductEntryInfo'
                            Times   = 1
                        }
                    )

                    $expectedReturnValue = $script:mockProductEntryInfo

                    Invoke-GetTargetResourceUnitTest -GetTargetResourceParameters $getTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ExpectedReturnValue $expectedReturnValue
                }
            }

            Describe 'xMsiPackage\Set-TargetResource' {
                $setTargetResourceParameters = @{
                    ProductId                           = 'TestProductId'
                    Path                                = $script:testPath
                    Ensure                              = 'Present'
                    Arguments                           = 'TestArguments'
                    LogPath                             = 'TestLogPath'
                    FileHash                            = 'TestFileHash'
                    HashAlgorithm                       = 'Sha256'
                    SignerSubject                       = 'TestSignerSubject'
                    SignerThumbprint                    = 'TestSignerThumbprint'
                    ServerCertificateValidationCallback = 'TestValidationCallback'
                    RunAsCredential                     = $script:testCredential
                    Verbose                             = $true
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriNonUnc }
                Mock -CommandName 'Convert-ProductIdToIdentifyingNumber' -MockWith { return $script:testIdentifyingNumber }
                Mock -CommandName 'Assert-PathExtensionValid' -MockWith { }
                Mock -CommandName 'New-LogFile' -MockWith { }
                Mock -CommandName 'New-PSDrive' -MockWith { return $script:mockPSDrive }
                Mock -CommandName 'Test-Path' -MockWith { return $true }
                Mock -CommandName 'New-Item' -MockWith { }
                Mock -CommandName 'New-Object' -MockWith { return $script:mockStream }
                Mock -CommandName 'Get-WebRequestResponse' -MockWith { return $script:mockStream }
                Mock -CommandName 'Copy-ResponseStreamToFileStream' -MockWith { }
                Mock -CommandName 'Close-Stream' -MockWith { }
                Mock -CommandName 'Assert-FileValid' -MockWith { }
                Mock -CommandName 'Get-MsiProductCode' -MockWith { return $script:testIdentifyingNumber }
                Mock -CommandName 'Start-MsiProcess' -MockWith {
                    # Returns the exit code
                    return 0
                }
                Mock -CommandName 'Remove-PSDrive' -MockWith { }
                Mock -CommandName 'Remove-Item' -MockWith { }
                Mock -CommandName 'Invoke-CimMethod' -MockWith { }
                Mock -CommandName 'Get-ItemProperty' -MockWith { return $null }
                Mock -CommandName 'Get-ProductEntry' -MockWith { return $script:mockProductEntry }

                Context 'When URI scheme is non-UNC file and installation succeeds' {
                    $mocksCalled = @(
                        @{ Command = 'Convert-PathToUri'; Times = 1 }
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Assert-PathExtensionValid'; Times = 1 }
                        @{ Command = 'New-LogFile'; Times = 1 }
                        @{ Command = 'New-PSDrive'; Times = 0 }
                        @{ Command = 'Get-WebRequestResponse'; Times = 0 }
                        @{ Command = 'Test-Path'; Times = 1; Custom = 'to the MSI file' }
                        @{ Command = 'Assert-FileValid'; Times = 1 }
                        @{ Command = 'Get-MsiProductCode'; Times = 1 }
                        @{ Command = 'Start-MsiProcess'; Times = 1 }
                        @{ Command = 'Remove-PSDrive'; Times = 0 }
                        @{ Command = 'Remove-Item'; Times = 0; Custom = 'the downloaded file from the http server' }
                        @{ Command = 'Invoke-CimMethod'; Times = 1 }
                        @{ Command = 'Get-ItemProperty'; Times = 1; Custom = 'the registry data for pending file rename operations' }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                    )

                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriFile }
                $setTargetResourceParameters.Ensure = 'Present'

                Context 'When URI scheme is UNC file and installation succeeds' {
                    $mocksCalled = @(
                        @{ Command = 'Convert-PathToUri'; Times = 1 }
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Assert-PathExtensionValid'; Times = 1 }
                        @{ Command = 'New-LogFile'; Times = 1 }
                        @{ Command = 'New-PSDrive'; Times = 1 }
                        @{ Command = 'Get-WebRequestResponse'; Times = 0 }
                        @{ Command = 'Test-Path'; Times = 1; Custom = 'to the MSI file' }
                        @{ Command = 'Assert-FileValid'; Times = 1 }
                        @{ Command = 'Get-MsiProductCode'; Times = 1 }
                        @{ Command = 'Start-MsiProcess'; Times = 1 }
                        @{ Command = 'Remove-PSDrive'; Times = 1 }
                        @{ Command = 'Remove-Item'; Times = 0; Custom = 'the downloaded file from the http server' }
                        @{ Command = 'Invoke-CimMethod'; Times = 1 }
                        @{ Command = 'Get-ItemProperty'; Times = 1; Custom = 'the registry data for pending file rename operations' }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                    )

                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriHttp }

                Context 'When URI scheme is Http and installation succeeds' {
                    $mocksCalled = @(
                        @{ Command = 'Convert-PathToUri'; Times = 1 }
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Assert-PathExtensionValid'; Times = 1 }
                        @{ Command = 'New-LogFile'; Times = 1 }
                        @{ Command = 'New-PSDrive'; Times = 0 }
                        @{ Command = 'Test-Path'; Times = 3; Custom = 'to the package cache' }
                        @{ Command = 'New-Item'; Times = 0; Custom = 'directory for the package cache' }
                        @{ Command = 'New-Object'; Times = 1; Custom = 'file stream to copy the response to' }
                        @{ Command = 'Get-WebRequestResponse'; Times = 1 }
                        @{ Command = 'Copy-ResponseStreamToFileStream'; Times = 1 }
                        @{ Command = 'Close-Stream'; Times = 2 }
                        @{ Command = 'Test-Path'; Times = 3; Custom = 'to the MSI file' }
                        @{ Command = 'Assert-FileValid'; Times = 1 }
                        @{ Command = 'Get-MsiProductCode'; Times = 1 }
                        @{ Command = 'Start-MsiProcess'; Times = 1 }
                        @{ Command = 'Remove-PSDrive'; Times = 0 }
                        @{ Command = 'Remove-Item'; Times = 1; Custom = 'the directory used for the package cache' }
                        @{ Command = 'Invoke-CimMethod'; Times = 1 }
                        @{ Command = 'Get-ItemProperty'; Times = 1; Custom = 'the registry data for pending file rename operations' }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                    )

                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriHttps }

                Context 'When URI scheme is Https and installation succeeds' {
                    $mocksCalled = @(
                        @{ Command = 'Convert-PathToUri'; Times = 1 }
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Assert-PathExtensionValid'; Times = 1 }
                        @{ Command = 'New-LogFile'; Times = 1 }
                        @{ Command = 'New-PSDrive'; Times = 0 }
                        @{ Command = 'Test-Path'; Times = 3; Custom = 'to the package cache' }
                        @{ Command = 'New-Item'; Times = 0; Custom = 'directory for the package cache' }
                        @{ Command = 'New-Object'; Times = 1; Custom = 'file stream to copy the response to' }
                        @{ Command = 'Get-WebRequestResponse'; Times = 1 }
                        @{ Command = 'Copy-ResponseStreamToFileStream'; Times = 1 }
                        @{ Command = 'Close-Stream'; Times = 2 }
                        @{ Command = 'Test-Path'; Times = 3; Custom = 'to the MSI file' }
                        @{ Command = 'Assert-FileValid'; Times = 1 }
                        @{ Command = 'Get-MsiProductCode'; Times = 1 }
                        @{ Command = 'Start-MsiProcess'; Times = 1 }
                        @{ Command = 'Remove-PSDrive'; Times = 0 }
                        @{ Command = 'Remove-Item'; Times = 1; Custom = 'the directory used for the package cache' }
                        @{ Command = 'Invoke-CimMethod'; Times = 1 }
                        @{ Command = 'Get-ItemProperty'; Times = 1; Custom = 'the registry data for pending file rename operations' }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                    )

                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Context 'When reboot required or not required' {
                    Mock -CommandName 'Start-MsiProcess' -MockWith { return 3010 }

                    It 'Should request reboot by default' {
                        Mock -CommandName 'Set-DscMachineRebootRequired'

                        $setTargetResourceParameters.IgnoreReboot = $false
                        { $null = Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw

                        Assert-MockCalled -CommandName 'Set-DscMachineRebootRequired' -Exactly -Times 1 -Scope It
                    }

                    It 'Should not request reboot if IgnoreReboot specified' {
                        Mock -CommandName 'Set-DscMachineRebootRequired'

                        $setTargetResourceParameters.IgnoreReboot = $true
                        { $null = Set-TargetResource @setTargetResourceParameters } | Should -Not -Throw

                        Assert-MockCalled -CommandName 'Set-DscMachineRebootRequired' -Exactly -Times 0 -Scope It
                    }
                }

                $setTargetResourceParameters.Ensure = 'Absent'

                # The URI scheme doesn't matter for uninstallation - it will always do the same thing
                Context 'When uninstallation succeeds' {
                    $mocksCalled = @(
                        @{ Command = 'Convert-PathToUri'; Times = 1 }
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Assert-PathExtensionValid'; Times = 1 }
                        @{ Command = 'New-LogFile'; Times = 1 }
                        @{ Command = 'New-PSDrive'; Times = 0 }
                        @{ Command = 'Get-WebRequestResponse'; Times = 0 }
                        @{ Command = 'Test-Path'; Times = 0; Custom = 'to the MSI file' }
                        @{ Command = 'Assert-FileValid'; Times = 0 }
                        @{ Command = 'Get-MsiProductCode'; Times = 0 }
                        @{ Command = 'Start-MsiProcess'; Times = 1 }
                        @{ Command = 'Remove-PSDrive'; Times = 0 }
                        @{ Command = 'Remove-Item'; Times = 0; Custom = 'the downloaded file from the http server' }
                        @{ Command = 'Invoke-CimMethod'; Times = 1 }
                        @{ Command = 'Get-ItemProperty'; Times = 1; Custom = 'the registry data for pending file rename operations' }
                        @{ Command = 'Get-ProductEntry'; Times = 0 }
                    )

                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriQuery }

                Context 'When path is a query path' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -ShouldThrow $false

                    It 'Should assert that the file without the query string has a valid extension' {
                        Assert-MockCalled -CommandName 'Assert-PathExtensionValid' -Exactly 1 -Scope 'Context' -ParameterFilter { $Path -eq (Split-Path -Path $script:testuriQuery.LocalPath -Leaf) }
                    }
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriOnlyFile }

                Context 'When converted URI does not have a local path' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -ShouldThrow $false

                    It 'Should assert that the original path has a valid extension' {
                        Assert-MockCalled -CommandName 'Assert-PathExtensionValid' -Exactly 1 -Scope 'Context' -ParameterFilter { $Path -eq $script:testPath }
                    }
                }

                $setTargetResourceParameters.Remove('LogPath')

                Context 'When converted URI does not have a local path' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -MocksCalled @(@{ Command = 'New-LogFile'; Times = 0 }) `
                        -ShouldThrow $false
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriHttp }
                Mock -CommandName 'Test-Path' -MockWith { return $false } -ParameterFilter { $Path -eq $script:packageCacheLocation }
                $setTargetResourceParameters.Ensure = 'Present'

                Context 'When URI scheme is Http and package cache location does not exist yet' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -MocksCalled @(@{ Command = 'New-Item'; Times = 1; Custom = 'directory for the package cache' }) `
                        -ShouldThrow $false
                }

                # Error Tests

                Mock -CommandName 'Get-ProductEntry' -MockWith { return $null }

                Context 'When package could not be found after installation' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -ShouldThrow $true `
                        -ErrorMessage ($script:localizedData.PostValidationError -f $setTargetResourceParameters.Path) `
                        -ErrorTestName $script:errorMessageTitles.PostValidationError
                }

                Mock -CommandName 'Get-MsiProductCode' -MockWith { return $script:testWrongProductId }

                Context 'When product code from downloaded MSI package does not match specified ID' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -ShouldThrow $true `
                        -ErrorMessage ($script:localizedData.InvalidId -f $script:testIdentifyingNumber, $script:testWrongProductId) `
                        -ErrorTestName $script:errorMessageTitles.InvalidId
                }

                Mock -CommandName 'New-Object' -MockWith { Throw }

                Context 'When failure while creating the file stream object to download to' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -ShouldThrow $true `
                        -ErrorMessage ($script:localizedData.CouldNotOpenDestFile -f $script:destinationPath) `
                        -ErrorTestName $script:errorMessageTitles.CouldNotOpenDestFile
                }

                Mock -CommandName 'Convert-PathToUri' -MockWith { return $script:testUriNonUnc }
                Mock -CommandName 'Test-Path' -MockWith { return $false } -ParameterFilter { $Path -eq $script:testPath }

                Context 'When invalid path was passed in' {
                    Invoke-SetTargetResourceUnitTest -SetTargetResourceParameters $setTargetResourceParameters `
                        -ShouldThrow $true `
                        -ErrorMessage ($script:localizedData.PathDoesNotExist -f $script:testPath) `
                        -ErrorTestName $script:errorMessageTitles.PathDoesNotExist
                }
            }

            Describe 'xMsiPackage\Test-TargetResource' {
                Mock -CommandName 'Convert-ProductIdToIdentifyingNumber' -MockWith { return $script:testIdentifyingNumber }
                Mock -CommandName 'Get-ProductEntry' -MockWith { return $script:mockProductEntry }
                Mock -CommandName 'Get-ProductEntryValue' -MockWith { return $script:mockProductEntryInfo.Name }

                Context 'When specified package is present and should be' {
                    $testTargetResourceParameters = @{
                        ProductId = $script:testProductId
                        Path      = $script:testPath
                        Ensure    = 'Present'
                        Verbose   = $true
                    }

                    $mocksCalled = @(
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                        @{ Command = 'Get-ProductEntryValue'; Times = 1 }
                    )

                    Invoke-TestTargetResourceUnitTest -TestTargetResourceParameters $testTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ExpectedReturnValue $true
                }

                Context 'When specified package is present but should not be' {
                    $testTargetResourceParameters = @{
                        ProductId = $script:testProductId
                        Path      = $script:testPath
                        Ensure    = 'Absent'
                    }

                    $mocksCalled = @(
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                        @{ Command = 'Get-ProductEntryValue'; Times = 1 }
                    )

                    Invoke-TestTargetResourceUnitTest -TestTargetResourceParameters $testTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ExpectedReturnValue $false
                }

                Mock -CommandName 'Get-ProductEntry' -MockWith { return $null }

                Context 'When specified package is Absent but should not be' {
                    $testTargetResourceParameters = @{
                        ProductId = $script:testProductId
                        Path      = $script:testPath
                        Ensure    = 'Present'
                    }

                    $mocksCalled = @(
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                        @{ Command = 'Get-ProductEntryValue'; Times = 0 }
                    )

                    Invoke-TestTargetResourceUnitTest -TestTargetResourceParameters $testTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ExpectedReturnValue $false
                }

                Context 'When specified package is Absent and should be' {
                    $testTargetResourceParameters = @{
                        ProductId = $script:testProductId
                        Path      = $script:testPath
                        Ensure    = 'Absent'
                    }

                    $mocksCalled = @(
                        @{ Command = 'Convert-ProductIdToIdentifyingNumber'; Times = 1 }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                        @{ Command = 'Get-ProductEntryValue'; Times = 0 }
                    )

                    Invoke-TestTargetResourceUnitTest -TestTargetResourceParameters $testTargetResourceParameters `
                        -MocksCalled $mocksCalled `
                        -ExpectedReturnValue $true
                }
            }

            Describe 'xMsiPackage\Assert-PathExtensionValid' {
                Context 'When path is a valid .msi path' {
                    It 'Should not throw' {
                        { Assert-PathExtensionValid -Path 'testMsiFile.msi' } | Should -Not -Throw
                    }
                }

                Context 'When path is not a valid .msi path' {
                    It 'Should throw an invalid argument exception when an EXE file is passed in' {
                        $invalidPath = 'testMsiFile.exe'
                        $expectedErrorMessage = ($script:localizedData.InvalidBinaryType -f $invalidPath)

                        { Assert-PathExtensionValid -Path $invalidPath } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }

                    It 'Should throw an invalid argument exception when an invalid file type is passed in' {
                        $invalidPath = 'testMsiFilemsi'
                        $expectedErrorMessage = ($script:localizedData.InvalidBinaryType -f $invalidPath)

                        { Assert-PathExtensionValid -Path $invalidPath } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }
            }

            Describe 'xMsiPackage\Convert-PathToUri' {
                Context 'When path has a valid URI scheme' {
                    It 'Should return the expected URI when scheme is a file' {
                        $filePath = (Join-Path -Path $PSScriptRoot -ChildPath 'testMsi.msi')
                        $expectedReturnValue = [System.Uri] $filePath

                        Convert-PathToUri -Path $filePath | Should -Be $expectedReturnValue
                    }

                    It 'Should return the expected URI when scheme is http' {
                        $uriBuilder = [System.UriBuilder]::new('http', 'localhost')
                        $uriBuilder.Path = 'testMsi.msi'
                        $filePath = $uriBuilder.Uri.AbsoluteUri

                        Convert-PathToUri -Path $filePath | Should -Be $uriBuilder.Uri
                    }

                    It 'Should return the expected URI when scheme is https' {
                        $uriBuilder = [System.UriBuilder]::new('https', 'localhost')
                        $uriBuilder.Path = 'testMsi.msi'
                        $filePath = $uriBuilder.Uri.AbsoluteUri

                        Convert-PathToUri -Path $filePath | Should -Be $uriBuilder.Uri
                    }
                }

                Context 'When invalid path passed in' {
                    It 'Should throw an error when uri scheme is invalid' {
                        $filePath = 'ht://localhost/testMsi.msi'
                        $expectedErrorMessage = ($script:localizedData.InvalidPath -f $filePath)

                        { Convert-PathToUri -Path $filePath } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }

                    It 'Should throw an error when path is not in valid format' {
                        $filePath = 'mri'
                        $expectedErrorMessage = ($script:localizedData.InvalidPath -f $filePath)

                        { Convert-PathToUri -Path $filePath } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }
            }

            Describe 'xMsiPackage\Convert-ProductIdToIdentifyingNumber' {
                Context 'When valid product ID is passed in' {
                    It 'Should return the same value that is passed in when the Product ID is already in the correct format' {
                        Convert-ProductIdToIdentifyingNumber -ProductId $script:testIdentifyingNumber | Should -Be $script:testIdentifyingNumber
                    }

                    It 'Should convert a valid poduct ID to the identifying number format' {
                        Convert-ProductIdToIdentifyingNumber -ProductId $script:testProductId | Should -Be $script:testIdentifyingNumber
                    }
                }

                Context 'When invalid Product ID is passed in' {
                    It 'Should throw an exception when an invalid product ID is passed in' {
                        $expectedErrorMessage = ($script:localizedData.InvalidIdentifyingNumber -f $script:testWrongProductId)
                        { Convert-ProductIdToIdentifyingNumber -ProductId $script:testWrongProductId } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }
            }

            Describe 'xMsiPackage\Get-ProductEntry' {
                $uninstallRegistryKeyLocation = (Join-Path -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' -ChildPath $script:testIdentifyingNumber)
                $uninstallRegistryKeyWow64Location = (Join-Path -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' -ChildPath $script:testIdentifyingNumber)

                Mock -CommandName 'Get-Item' -MockWith { return $script:mockProductEntry } -ParameterFilter { $Path -eq $uninstallRegistryKeyLocation }
                Mock -CommandName 'Get-Item' -MockWith { return $script:mockProductEntry } -ParameterFilter { $Path -eq $uninstallRegistryKeyWow64Location }

                Context 'When product entry is found in the expected location' {
                    It 'Should return the expected product entry' {
                        Get-ProductEntry -IdentifyingNumber $script:testIdentifyingNumber | Should -Be $script:mockProductEntry
                    }

                    It 'Should retrieve the item' {
                        Assert-MockCalled -CommandName 'Get-Item' -Exactly 1 -Scope 'Context'
                    }
                }

                Mock -CommandName 'Get-Item' -MockWith { return $null } -ParameterFilter { $Path -eq $uninstallRegistryKeyLocation }

                Context 'When product entry is found under Wow6432Node' {
                    It 'Should return the expected product entry' {
                        Get-ProductEntry -IdentifyingNumber $script:testIdentifyingNumber | Should -Be $script:mockProductEntry
                    }

                    It 'Should attempt to retrieve the item twice' {
                        Assert-MockCalled -CommandName 'Get-Item' -Exactly 2 -Scope 'Context'
                    }
                }

                Mock -CommandName 'Get-Item' -MockWith { return $null } -ParameterFilter { $Path -eq $uninstallRegistryKeyWow64Location }

                Context 'When product entry is not found' {
                    It 'Should return $null' {
                        Get-ProductEntry -IdentifyingNumber $script:testIdentifyingNumber | Should -Be $null
                    }

                    It 'Should attempt to retrieve the item twice' {
                        Assert-MockCalled -CommandName 'Get-Item' -Exactly 2 -Scope 'Context'
                    }
                }
            }

            Describe 'xMsiPackage\Get-ProductEntryInfo' {
                Mock -CommandName Get-ProductEntryValue -MockWith { return '20170404' } -ParameterFilter { $Property -eq 'InstallDate' }
                Mock -CommandName Get-ProductEntryValue -MockWith { return $script:mockProductEntryInfo.Publisher } -ParameterFilter { $Property -eq 'Publisher' }
                Mock -CommandName Get-ProductEntryValue -MockWith { return $script:mockProductEntryInfo.Size } -ParameterFilter { $Property -eq 'EstimatedSize' }
                Mock -CommandName Get-ProductEntryValue -MockWith { return $script:mockProductEntryInfo.Version } -ParameterFilter { $Property -eq 'DisplayVersion' }
                Mock -CommandName Get-ProductEntryValue -MockWith { return $script:mockProductEntryInfo.PackageDescription } -ParameterFilter { $Property -eq 'Comments' }
                Mock -CommandName Get-ProductEntryValue -MockWith { return $script:mockProductEntryInfo.Name } -ParameterFilter { $Property -eq 'DisplayName' }
                Mock -CommandName Get-ProductEntryValue -MockWith { return $script:mockProductEntryInfo.InstallSource } -ParameterFilter { $Property -eq 'InstallSource' }

                Context 'When all properties are retrieved successfully' {
                    $getProductEntryInfoResult = Get-ProductEntryInfo -ProductEntry $script:mockProductEntry

                    It 'Should return the expected installed date' {
                        $getProductEntryInfoResult.InstalledOn | Should -Be $script:mockProductEntryInfo.InstalledOn
                    }

                    It 'Should return the expected publisher' {
                        $getProductEntryInfoResult.Publisher | Should -Be $script:mockProductEntryInfo.Publisher
                    }

                    It 'Should return the expected size' {
                        $getProductEntryInfoResult.Size | Should -Be ($script:mockProductEntryInfo.Size / 1024)
                    }

                    It 'Should return the expected Version' {
                        $getProductEntryInfoResult.Version | Should -Be $script:mockProductEntryInfo.Version
                    }

                    It 'Should return the expected package description' {
                        $getProductEntryInfoResult.PackageDescription | Should -Be $script:mockProductEntryInfo.PackageDescription
                    }

                    It 'Should return the expected name' {
                        $getProductEntryInfoResult.Name | Should -Be $script:mockProductEntryInfo.Name
                    }

                    It 'Should return the expected install source' {
                        $getProductEntryInfoResult.InstallSource | Should -Be $script:mockProductEntryInfo.InstallSource
                    }

                    It 'Should retrieve 7 product entry values' {
                        Assert-MockCalled -CommandName 'Get-ProductEntryValue' -Exactly 7 -Scope 'Context'
                    }
                }

                Mock -CommandName Get-ProductEntryValue -MockWith { return '4/4/2017' } -ParameterFilter { $Property -eq 'InstallDate' }

                Context 'When install date is in incorrect format' {
                    $getProductEntryInfoResult = Get-ProductEntryInfo -ProductEntry $script:mockProductEntry

                    It 'Should return $null for InstalledOn' {
                        $getProductEntryInfoResult.InstalledOn | Should -Be $null
                    }
                }
            }

            Describe 'xMsiPackage\New-LogFile' {
                Mock -CommandName 'Test-Path' -MockWith { return $true }
                Mock -CommandName 'Remove-Item' -MockWith { }
                Mock -CommandName 'New-Item' -MockWith { }

                Context 'When file with name of given log file already exists and creation of new log file succeeds' {
                    $mocksCalled = @(
                        @{ Command = 'Test-Path'; Times = 1; Custom = 'to the log file' }
                        @{ Command = 'Remove-Item'; Times = 1; Custom = 'any file with the same name as the log file' }
                        @{ Command = 'New-Item'; Times = 1; Custom = 'log file' }
                    )

                    Invoke-GenericUnitTest -Function { Param($script:testPath) New-LogFile $script:testPath } `
                        -FunctionParameters @{ LogPath = $script:testPath } `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Mock -CommandName 'Test-Path' -MockWith { return $false }

                Context 'When file with name of given log file does not exist and creation of new log file succeeds' {
                    $mocksCalled = @(
                        @{ Command = 'Test-Path'; Times = 1; Custom = 'to the log file' }
                        @{ Command = 'Remove-Item'; Times = 0; Custom = 'any file with the same name as the log file' }
                        @{ Command = 'New-Item'; Times = 1; Custom = 'log file' }
                    )

                    Invoke-GenericUnitTest -Function { Param($script:testPath) New-LogFile $script:testPath } `
                        -FunctionParameters @{ LogPath = $script:testPath } `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Mock -CommandName 'New-Item' -MockWith { Throw }

                Context 'When creation of new log file fails' {
                    Invoke-GenericUnitTest -Function { Param($script:testPath) New-LogFile $script:testPath } `
                        -FunctionParameters @{ LogPath = $script:testPath } `
                        -ShouldThrow $true `
                        -ErrorMessage ($script:localizedData.CouldNotOpenLog -f $script:testPath) `
                        -ErrorTestName $script:errorMessageTitles.CouldNotOpenLog
                }
            }

            Describe 'xMsiPackage\Get-WebRequestResponse' {
                Mock -CommandName 'Get-WebRequest' -MockWith { return $script:mockWebRequest }
                Mock -CommandName 'Get-ScriptBlock' -MockWith { return { Write-Verbose 'Hello World' } }
                Mock -CommandName 'Get-WebRequestResponseStream' -MockWith { return $script:mockStream }

                Context 'When URI scheme is Http and response is successfully retrieved' {
                    $mocksCalled = @(
                        @{ Command = 'Get-WebRequest'; Times = 1 }
                        @{ Command = 'Get-ScriptBlock'; Times = 0 }
                        @{ Command = 'Get-WebRequestResponseStream'; Times = 1 }
                    )

                    It 'Should return the expected response stream' {
                        Get-WebRequestResponse -Uri $script:testUriHttp | Should -Be $script:mockStream
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Context 'When URI scheme is Https with no callback and response is successfully retrieved' {
                    $mocksCalled = @(
                        @{ Command = 'Get-WebRequest'; Times = 1 }
                        @{ Command = 'Get-ScriptBlock'; Times = 0 }
                        @{ Command = 'Get-WebRequestResponseStream'; Times = 1 }
                    )

                    It 'Should return the expected response stream' {
                        Get-WebRequestResponse -Uri $script:testUriHttps | Should -Be $script:mockStream
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Context 'When URI scheme is Https with callback and response is successfully retrieved' {
                    $mocksCalled = @(
                        @{ Command = 'Get-WebRequest'; Times = 1 }
                        @{ Command = 'Get-ScriptBlock'; Times = 1 }
                        @{ Command = 'Get-WebRequestResponseStream'; Times = 1 }
                    )

                    It 'Should return the expected response stream' {
                        Get-WebRequestResponse -Uri $script:testUriHttps -ServerCertificateValidationCallback 'TestCallbackFunction' | Should -Be $script:mockStream
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Mock -CommandName 'Get-WebRequestResponseStream' -MockWith { Throw }

                Context 'When error occurred during while retrieving the response' {
                    It 'Should throw the expected exception' {
                        $expectedErrorMessage = ($script:localizedData.CouldNotGetResponseFromWebRequest -f $script:testUriHttp.Scheme, $script:testUriHttp.OriginalString)
                        { Get-WebRequestResponse -Uri $script:testUriHttp } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }
            }

            Describe 'xMsiPackage\Assert-FileValid' {
                Mock -CommandName 'Assert-FileHashValid' -MockWith { }
                Mock -CommandName 'Assert-FileSignatureValid' -MockWith { }

                Context 'When FileHash is passed in and SignerThumbprint and SignerSubject are not' {
                    $mocksCalled = @(
                        @{ Command = 'Assert-FileHashValid'; Times = 1 }
                        @{ Command = 'Assert-FileSignatureValid'; Times = 0 }
                    )

                    It 'Should not throw' {
                        { Assert-FileValid -Path $script:testPath -FileHash 'mockFileHash' } | Should -Not -Throw
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Context 'When FileHash and SignerThumbprint are passed in but SignerSubject is not' {
                    $mocksCalled = @(
                        @{ Command = 'Assert-FileHashValid'; Times = 1 }
                        @{ Command = 'Assert-FileSignatureValid'; Times = 1 }
                    )

                    It 'Should not throw' {
                        { Assert-FileValid -Path $script:testPath -FileHash 'mockFileHash' -SignerThumbprint 'mockSignerThumbprint' } | Should -Not -Throw
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Context 'When only Path and SignerSubject are passed in' {
                    $mocksCalled = @(
                        @{ Command = 'Assert-FileHashValid'; Times = 0 }
                        @{ Command = 'Assert-FileSignatureValid'; Times = 1 }
                    )

                    It 'Should not throw' {
                        { Assert-FileValid -Path $script:testPath -SignerSubject 'mockSignerSubject' } | Should -Not -Throw
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Context 'When FileHash, SignerThumbprint, and SignerSubject are passed in' {
                    $mocksCalled = @(
                        @{ Command = 'Assert-FileHashValid'; Times = 1 }
                        @{ Command = 'Assert-FileSignatureValid'; Times = 1 }
                    )

                    It 'Should not throw' {
                        { Assert-FileValid -Path $script:testPath -FileHash 'mockFileHash' `
                                -SignerThumbprint 'mockSignerThumbprint' `
                                -SignerSubject 'mockSignerSubject'
                        } | Should -Not -Throw
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Context 'When SignerThumbprint and SignerSubject are passed in but FileHash is not' {
                    $mocksCalled = @(
                        @{ Command = 'Assert-FileHashValid'; Times = 0 }
                        @{ Command = 'Assert-FileSignatureValid'; Times = 1 }
                    )

                    It 'Should not throw' {
                        { Assert-FileValid -Path $script:testPath -SignerThumbprint 'mockSignerThumbprint' `
                                -SignerSubject 'mockSignerSubject'
                        } | Should -Not -Throw
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }

                Context 'When only path is passed in' {
                    $mocksCalled = @(
                        @{ Command = 'Assert-FileHashValid'; Times = 0 }
                        @{ Command = 'Assert-FileSignatureValid'; Times = 0 }
                    )

                    It 'Should not throw' {
                        { Assert-FileValid -Path $script:testPath } | Should -Not -Throw
                    }

                    Invoke-ExpectedMocksAreCalledTest -MocksCalled $mocksCalled
                }
            }

            Describe 'xMsiPackage\Assert-FileHashValid' {
                $mockHash = @{ Hash = 'testHash' }
                Mock -CommandName 'Get-FileHash' -MockWith { return $mockHash }

                Context 'When file hash is valid' {
                    It 'Should not throw when hashes match' {
                        { Assert-FileHashValid -Path $script:testPath -Hash $mockHash.Hash -Algorithm 'SHA256' } | Should -Not -Throw
                    }

                    It 'Should fetch the file hash' {
                        Assert-MockCalled -CommandName 'Get-FileHash' -Exactly 1 -Scope 'Context'
                    }
                }

                Context 'When file hash is invalid' {
                    $badHash = 'BadHash'
                    $expectedErrorMessage = ($script:localizedData.InvalidFileHash -f $script:testPath, $badHash, 'SHA256')

                    It 'Should throw when hashes do not match' {
                        { Assert-FileHashValid -Path $script:testPath -Hash $badHash -Algorithm 'SHA256' } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }
            }

            Describe 'xMsiPackage\Assert-FileSignatureValid' {
                $mockThumbprint = 'mockThumbprint'
                $mockSubject = 'mockSubject'
                $mockSignature = @{
                    Status            = [System.Management.Automation.SignatureStatus]::Valid
                    SignerCertificate = @{ Thumbprint = $mockThumbprint; Subject = $mockSubject }
                }

                Mock -CommandName 'Get-AuthenticodeSignature' -MockWith { return $mockSignature }

                Context 'When file signature status, thumbprint and subject are valid' {
                    It 'Should not throw' {
                        { Assert-FileSignatureValid -Path $script:testPath -Thumbprint $mockThumbprint -Subject $mockSubject } | Should -Not -Throw
                    }
                }

                Context 'When file signature status and thumbprint are valid and Subject not passed in' {
                    It 'Should not throw' {
                        { Assert-FileSignatureValid -Path $script:testPath -Thumbprint $mockThumbprint } | Should -Not -Throw
                    }
                }

                Context 'When file signature status and subject are valid and Thumbprint not passed in' {
                    It 'Should not throw' {
                        { Assert-FileSignatureValid -Path $script:testPath -Subject $mockSubject } | Should -Not -Throw
                    }
                }

                Context 'When only path is passed in' {
                    It 'Should not throw' {
                        { Assert-FileSignatureValid -Path $script:testPath } | Should -Not -Throw
                    }
                }

                Context 'When File signature status and thumbprint are valid and subject is invalid' {
                    $badSubject = 'BadSubject'
                    $expectedErrorMessage = ($script:localizedData.WrongSignerSubject -f $script:testPath, $badSubject)

                    It 'Should throw expected error message' {
                        { Assert-FileSignatureValid -Path $script:testPath -Thumbprint $mockThumbprint -Subject $badSubject } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }

                Context 'When file signature status and subject are valid and thumbprint is invalid' {
                    $badThumbprint = 'BadThumbprint'
                    $expectedErrorMessage = ($script:localizedData.WrongSignerThumbprint -f $script:testPath, $badThumbprint)

                    It 'Should throw expected error message' {
                        { Assert-FileSignatureValid -Path $script:testPath -Thumbprint $badThumbprint -Subject $mockSubject } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }

                Context 'When file signature status is invalid and subject and thumbprint are valid' {
                    $mockSignature.Status = 'Invalid'
                    $expectedErrorMessage = ($script:localizedData.InvalidFileSignature -f $script:testPath, $mockSignature.Status)

                    It 'Should throw expected error message' {
                        { Assert-FileSignatureValid -Path $script:testPath -Thumbprint $mockThumbprint -Subject $mockSubject } | Should -Throw -ExpectedMessage $expectedErrorMessage
                    }
                }
            }

            Describe 'xMsiPackage\Start-MsiProcess' {
                Mock -CommandName 'New-Object' -MockWith { return $script:mockStartInfo } -ParameterFilter { $TypeName -eq 'System.Diagnostics.ProcessStartInfo' }
                Mock -CommandName 'New-Object' -MockWith { return $script:mockProcess } -ParameterFilter { $TypeName -eq 'System.Diagnostics.Process' }
                Mock -CommandName 'Get-ProductEntry' -MockWith { return $script:mockProductEntryInfo }
                Mock -CommandName 'Invoke-PInvoke' -MockWith { return 0 }
                Mock -CommandName 'Invoke-Process' -MockWith { return 0 }

                $startMsiProcessParameters = @{
                    IdentifyingNumber = $script:testIdentifyingNumber
                    Path              = $script:testPath
                    Ensure            = 'Present'
                    Arguments         = 'TestArguments'
                    LogPath           = 'TestLogPath'
                    RunAsCredential   = $script:testCredential
                }

                Context 'When install MSI package with RunAsCredential specified' {
                    $mocksCalled = @(
                        @{ Command = 'New-Object'; Times = 1; Custom = 'process start info object' }
                        @{ Command = 'Get-ProductEntry'; Times = 0 }
                        @{ Command = 'Invoke-PInvoke'; Times = 1; Custom = 'install' }
                        @{ Command = 'Invoke-Process'; Times = 0; Custom = 'install' }
                    )

                    Invoke-GenericUnitTest -Function { Param($startMsiProcessParameters) Start-MsiProcess @startMsiProcessParameters } `
                        -FunctionParameters $startMsiProcessParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                $startMsiProcessParameters.Ensure = 'Absent'

                Context 'When Uninstall MSI package with RunAsCredential specified' {
                    $mocksCalled = @(
                        @{ Command = 'New-Object'; Times = 1; Custom = 'process start info object' }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                        @{ Command = 'Invoke-PInvoke'; Times = 1; Custom = 'uninstall' }
                        @{ Command = 'Invoke-Process'; Times = 0; Custom = 'uninstall' }
                    )

                    Invoke-GenericUnitTest -Function { Param($startMsiProcessParameters) Start-MsiProcess @startMsiProcessParameters } `
                        -FunctionParameters $startMsiProcessParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                $startMsiProcessParameters.Ensure = 'Present'
                $startMsiProcessParameters.Remove('RunAsCredential')

                Context 'When install MSI package without RunAsCredential' {
                    $mocksCalled = @(
                        @{ Command = 'New-Object'; Times = 2; Custom = 'process start info object and process' }
                        @{ Command = 'Get-ProductEntry'; Times = 0 }
                        @{ Command = 'Invoke-PInvoke'; Times = 0; Custom = 'install' }
                        @{ Command = 'Invoke-Process'; Times = 1; Custom = 'install' }
                    )

                    Invoke-GenericUnitTest -Function { Param($startMsiProcessParameters) Start-MsiProcess @startMsiProcessParameters } `
                        -FunctionParameters $startMsiProcessParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                $startMsiProcessParameters.Ensure = 'Absent'

                Context 'When uninstall MSI package without RunAsCredential' {
                    $mocksCalled = @(
                        @{ Command = 'New-Object'; Times = 2; Custom = 'process start info object and process object' }
                        @{ Command = 'Get-ProductEntry'; Times = 1 }
                        @{ Command = 'Invoke-PInvoke'; Times = 0; Custom = 'uninstall' }
                        @{ Command = 'Invoke-Process'; Times = 1; Custom = 'uninstall' }
                    )

                    Invoke-GenericUnitTest -Function { Param($startMsiProcessParameters) Start-MsiProcess @startMsiProcessParameters } `
                        -FunctionParameters $startMsiProcessParameters `
                        -MocksCalled $mocksCalled `
                        -ShouldThrow $false
                }

                Mock -CommandName 'Invoke-Process' -MockWith { Throw }

                Context 'When error occurred while trying to invoke the process' {
                    Invoke-GenericUnitTest -Function { Param($startMsiProcessParameters) Start-MsiProcess @startMsiProcessParameters } `
                        -FunctionParameters $startMsiProcessParameters `
                        -ShouldThrow $true `
                        -ErrorMessage ($script:localizedData.CouldNotStartProcess -f $script:testPath) `
                        -ErrorTestName $script:errorMessageTitles.CouldNotStartProcess
                }
            }
        }
    }
}
finally
{
    Invoke-TestCleanup
}

redpajama_set_name: RedPajamaGithub


text:
Danimal Cannon
Experimental, Game Music
Rhythm Game Just Shapes & Beats Now Out for Nintendo Switch
June 1, 2018 | Brenna Wilkes | Comment? Share this Rhythm Game Just Shapes & Beats Now Out for Nintendo Switch
Publisher and developer Berzerk Studios have finally released their rhythm game Just Shapes & Beats for the Nintendo Switch and Steam, featuring a ton of chiptune and EDM artists including those from the VGM community. The game is exactly what is on the label; a fast-paced SHUMP featuring shapes (both you and your enemies) all moving to ridiculously speedy beats as you struggle to stay alive. (fyi, you won't for very long in most cases)
"Just Shapes & Beats" is a trippy couch-coop musical bullet-hell based on two simple things, there's going to be Shapes, and some kick-ass beats, and you are going to die a lot. Wait, that's three things, just go back and edit the first part to "three simple things" in your head.
The game won accolades at PAX East and South 2015 as well as Game Developer's Conference 2015 for its simple entertainment as a rhythm game. It also features the musical talents of familiar faces in the chiptune and EDM scene, including Danimal Cannon and Zef, Big Giant Circles, Kubbi and more. There's also teasing of additional tracks being added by more artists in the near future.
The game is currently on Steam for $17.99 and the Nintendo Store for $19.99. Check it out and be sure to tell us what you think!
Chip Music, Events, Game Music
RE:Play Expo 2016 to Feature Danimal Cannon, Bitshifter & More
June 16, 2016 | Brenna Wilkes | Comment? Share this RE:Play Expo 2016 to Feature Danimal Cannon, Bitshifter & More
The gaming and music event RE:Play is returning this year to Houston, Texas on July 2nd for another round of, well, gaming and music fun!
An event created in Houston, TX that centers around the love of gaming and the music it inspires combined. It is designed to be an outlet for game developers and musicians to perform and showcase their material, as well as fans to celebrate their love of gaming!
This time around, RE:Play has partnered with Lazybit Collective and will be featuring new games and arcades for your gaming pleasure. They also will be featuring a new lineup of musical guests and performers to tantalize your earmeats. The performer lineup is:
Danimal Cannon danimalcannon.com/
Bit Shifter bit.shifter.net/
SIXIXIX soundcloud.com/sixixix
Dual Core dualcoremusic.com
Ten Pixels Tall soundcloud.com/ten-pixels-tall
Broken Satellite soundcloud.com/brokensatellite
Float soundcloud.com/lbc-float
OVERCRASH soundcloud.com/era2077
Squincy Jones soundcloud.com/squincyjones
The event is currently $15 per ticket for the early bird pre-order, and more information can be found on their website.
Chip Music, Game Music
Joshua Morse returns for Halloween with VLAD II Castlevania EP
October 28, 2015 | Shawn Sackenheim | Comment? Share this Joshua Morse returns for Halloween with VLAD II Castlevania EP
GameChops has just released a follow up to Joshua Morse's spectacular 2013 Castlevania tribute album, VLAD, appropriately titled VLAD II. Like the original, VLAD II features four tracks of EDM chiptune/jazz fusion, this time with guest guitarist, Danimal Cannon, on two tracks. You can sample all four songs in the teaser video or listen over on bandcamp and check out the track listing below.
VLAD II is out now and available to buy from Loudr.fm for a minimum price of $4; just in time to pump up your Halloween week festivities. And for a limited time you can get both VLAD albums for a minimum of $7.
Bone Ark Madness (Symphony of the Night – Rainbow Cemetery)
Aqua Flash (Castlevania 3 – Aquarius)
Mummy Lover (Castlevania – Wicked Child)
Halfway to Hell (Castlevania – Heart of Fire)
New Kickstarter Featuring Music by Jake Kaufman and Danimal Cannon
July 24, 2014 | Brenna Wilkes | Comment? Share this New Kickstarter Featuring Music by Jake Kaufman and Danimal Cannon
Because Jake "Virt" Kaufman can't seem to take a break if he tried, it looks like he's involved with yet another Kickstarter project hot off the heels of the recent release of his fantastic work on Shovel Knight. This time around, however, it's for VR systems such as the Oculus, putting it in a unique position. Vanguard Valkyrie is a 3rd-person rail shooter designed for virtual reality headsets and looks quite impression gameplay-wise. The music is sure to rank right up there with the gameplay (and maybe even beyond) as Kaufman is also joined by guitarist Dan "Danimal Cannon" Behrens (ArmCannon, Metroid Metal) and newcomer musician Meganeko.
Vanguard Valyrie sports the very hefty pricetag of $198,000 for a game meant for a still very-new market in virtual reality. The major of people who currently have access to an Oculus Rift are game media and developers, and the pricetag for the general public is steep for new hardware that isn't even in its final form. While I have my own opinions about the success of such a lofty project, there's no doubt Virt and Danimal Cannon will be rocking the music for the game to the high echelons of awesome.
Vanguard Valkyrie by Zero Transform on Kickstarter
Chip Music, Game Music, Indie Music
MAGFest 12: Recap
January 15, 2014 | Michael Hoffmann | 1 Comment Share this MAGFest 12: Recap
A new year has begun and with it another MAGFest down in National Harbor, Maryland. This was my second year attending the annual Music and Game Festival. There's always a ton of things to do, from attending panels to rocking out at the concerts. Now that I've had a chance to recover from the trip and gather my thoughts, it's time for a recap of some of what I experienced at MAGFest 12.
Most of the panels I attended were focused on music. The first of these was the "Write Your Own Nintendo Music," hosted by Brendan "Inverse Phase" Becker. His talk focused on the tools that he uses for creating 8-bit/chiptune tracks for his music projects. He explained the methods in which music on the Gameboy and Nintendo Entertainment System was generated and what the musical and technological limitations for each were. Since this year's MAGFest was Zelda themed, he included a demonstration of 8-bit music writing by reconstructing the "Dungeon Theme" from The Legend of Zelda.
Brenden "Inverse Phase" Becker
Two of the other music panels that I attended were hosted by game composer Tommy Tallarico. He's probably best known for his soundtracks for Earthworm Jim and his work as the head of Video Games Live. The first panel "Video Games Live: Behind the Scenes" focused on his work with the orchestra program that he tours with around the world. Tallarico spent a majority of the time telling the audience stories about his experiences performing videogame music and revealed some of his upcoming arrangements for the orchestra. (more…)
Chip Music, Featured, Music Production, Software
Chiptune TED talk features Dan Behrens (Danimal Cannon) at TEDxBuffalo
November 16, 2013 | Haroon Piracha | Comment? Share this Chiptune TED talk features Dan Behrens (Danimal Cannon) at TEDxBuffalo
TED talks have always been about presenting ideas worth spreading, so I'm glad to see they've put Chiptunes on display. TED talks try to gain a deeper discussion in a local field, TEDx is more for local programs, and Dan (Dan Behrens, aka Danimal Cannon) hit it off. As Dan described Chiptunes, he defined it as…
… Any music made using, or emulating the sound of, old video game consoles and their soundchips.
-Danimal Cannon
Technically with that definition, the PS4 could also be considered platform for Chiptunes, but it's the sound that Dan and the others are attracted to, not particularly a beefy console. Dan's chip of choice being a classic Gameboy, he continued into his list of consoles that other artists use to make Chiptunes. Consoles such as the NES, Genesis, Commodore 64, Atari Amiga, and many others. As Dan described, it's really about taking minimalist hardware, and pushing it to the maximum potential.
The talk itself features some excellent music past the 4:35 mark. Take a listen.
Dan went further to talk about a trend taking place in music software, one that makes music controls easier to use, but leaves you ignorant to what the controls directly changed to achieve its sound. For instance, if you use a plug-in that has a fader controlling a "Smash" parameter, what is the "Smash" doing exactly? Does it EQ the sound? Is something being filtered? Does it matter? By using plug-ins like that, Dan considered it a failing to learn.
Dan also stated that such software is good for businesses, which is true. Music software that gives the end user the sounds they desire is often the goal developers strive for. However, Dan insisted that Chiptune is not a response to such easy-to-use music software, but rather it evolved by itself into where it currently stands in the community.
What are your thoughts on the subject? Do you agree that simple and easy to use software actually does make you less curious about how the sound was achieved?
MAGFest 12 Concert Line-up Announced
November 16, 2013 | Michael Hoffmann | Comment? Share this MAGFest 12 Concert Line-up Announced
Clear your calenders for the first weekend of 2014 and get ready to rock out to some phenomenal videogame music! The twelfth annual Music and Game Festival, also known as MAGFest 12, has released the performance roster for three of its upcoming videogame music concerts. The event will be taking place in National Harbor, Maryland and will run from January 2, 2014 through January 5, 2014. Two of these concerts are chiptune showcases, which will be held on Friday and Saturday afternoon. The Friday night concert will be what is known as an Electronic Dance Music (EDM) Battle concert. A total of six different DJs from the VGM community will be participating to perform their repertoire for this EDM Battle. The line-up for the upcoming concerts include some new acts and a number of returning artists.
The MAGFest 12 performance roster is as follows:
Friday Chiptune Showcase (12 PM – 2 PM)
– Trey Frey
– Chipocrite
– A_Rival
– Danimal Cannon
Friday Night EDM Battle (10 PM – 2 AM)
– bLiNd
– Benjamin Briggs
– DJ Cutman
– Grimecraft
– Totentaz
– Flexstyle
Saturday Chiptune Showcase (12 PM – 2 PM)
– Awesome Force
– Auxide
– Rainbow Dragon Eyes
– Cheap Dinosaurs
More information and updates on MAGFest events, tickets, hotels, special guests, and performers is available on the official MAGFest website at http://www.magfest.org/. A handful of us from Original Sound Version will be attending MAGFest 12 to cover the events and concerts as well. It's looking like a great line-up for this concert series. Hope to see you there.
Previous Entries »

redpajama_set_name: RedPajamaCommonCrawl


text:
Bush House continues a long journey of welcoming guests
By Staff | Dec 3, 2015
BARB BARRETT/The Luminary The Bush House in Muncy Township is now available for weddings and corporate functions. The home was originally built in the mid 1800s and boasts many unique features both inside and outside. The home is currently owned by the Alvin R. Bush family and co-managed by Hillside Catering.
MUNCY – With a long gleaming history, the Bush House in Muncy Township has taken on a new life. Inspired by its owner, Charlie Bush and a fellow entrepreneur and caterer, David Miele established the 8 acre mansion as a venue for parties, weddings, corporate entertainment, dinners, and meetings.
Originally part of the Samuel Wallis estate in the mid 1800's, it became the home of Margaret Jewett Hall who in 1867 added more square footage to the property, a large hall and two big rooms. It was only a small two story house when it was built in the 1840s according to Bush.
In 1912 the George Stearns family purchased the home and used it in the summer time. Therefore they built two large porches, and a barn to accomodate the horse and buggy they used to get back and forth to Williamsport.
A well known socialite from Olean, New York became the next owner and would entertain guests from Europe, New York and Philadelphia. She was influential for her interior design and did work for the governor's mansion as revealed by Bush during an interview with The Luminary. Her name was Louise Frachot and she married a local, prominent attorney, Ed Munson.
"She did beautiful work to the home," he said. She added elite wallpaper panels, marble floors, hand carved mahogany pillars, walnut stairs. "She knew the curators and went to their warehouses," said Bush. "In the powder room is Marie Antoinette's original boudoir brought back from France." A 3 story free standing spiral staircase is also appealing, and only 3 others are like this in the world. "At the time, it was thought to be architecturally impossible." A bedroom became a "ship room" for a small child with a desk intact that came from Admiral Nelson's fleet in Britain during the Battle of Trafalgar. Origingal wall paper can be seen in the dining room.
One of the dining rooms at the Bush House is set up for a corporate luncheon.
Bush explained that a lot of the home's history was recorded with the house, and original blueprits and work logs were discovered in the desk drawer in the upstairs ship room. Louise Munson also built two cottages on the property that were used as guest houses and possibly for staff. She named it the "Wyno Farm" and technically it is still named as such as it is recorded in "Homes and Heritage" a historical compilation of old homes and mansions in Lycoming County. It means "welcome, hello, or good luck" and its origin is native American. "The house is now referred to as 'The Bush House'."
After Mr. Munson passed away, in the mid 1920s, the 325 acre farm was purchased by Dr. Roy Simon who turned it into a home for very sick children suffering from tuberculosis and polio. He added a pool and started to build a great room, but in the process went bankrupt. The mansion remained vacant until 1945 when Alvin R. Bush, Charlie's grandfather, became the owner. "There was nothing here at the time, but a barn and the house," said Charlie referring to all the growth around him such as the mall and Grizzly Imports.
Al Bush was attracted to the trees and the aesthetic countryside. "He fell in love with the place," Charlie Bush reflected. "He spent 14 years here, and in 1950 he became Congressman." Lots of political dignitaries spent time here, probably sitting in these very rooms making decisions. There were many parties, social events and picnics. He served from 1951 to 1959
Charlie said his father moved into the home after World War II and he grew up with his brother and sisters. Horses and cattle were the way of life. There were no highways.
Charlie said his parents lived in the estate for awhile but had to downsize and moved to a smaller home in Williamsport.
Eventually the stables were torn down and now Target department store is located there. The main property remained vacant for about 8 years until two years ago when it was decided to transform the place into a desirable venue for just about any social gathering. "It became a private family corporation," Charlie said, "under the Bush name."
Now the events and parties can take place again as a catering venue from David Miele of Hillside Catering who has exclusive preparations for the food. After some extensive research, the decision to explore the idea got a tremendous response from the public. The first event was a wedding expo held last June. Since then, there have been several dinner meetings, a mystery dinner, corporate staff parties, a chamber exchange, birthday parties, and rehearsal dinners. Weddings are a major attraction and will feature a honeymoon suite which is in the renovation process as well completing 5 guest rooms upstairs with private baths.
Carmen Bush, Charlie's wife who is a master gardener, completed much of the landscaping adding flowers and covers for the grounds so that it is appealing all year long. "We are doing the right thing for the property, and bringing it back to its great splendor," said the couple.
For more information or to make a reservation for "the Bush House", call 570-368-8880 or wynofarms209@windstream.net.


Give your bike that little bit of extra with these Kitsch Kitchen saddle covers. With these unique covers, it will be impossible not to find your bike in the rush hour chaos. Moreover, your pants won't get wet after the rain! Designed with a beautiful black-white checkered print.
The Netherlands is known as a tulip country, country of the Golden Age and country of mills. In addition, our country has two more characteristics: love for cycling and changeable weather. Kitsch Kitchen responded to this and created these saddle covers. These saddle covers guarantee dry pants after a wet ride on your bike. The covers have a beautiful design, so you won't have to endlessly search for your bike in the rush hour chaos.
The cheerful design of this saddle brings a little color to your immediate surroundings. Combine multiple saddle covers with Kitsch Kitchen panniers and create a striking whole.
Kitsch Kitchen is a Dutch brand and offers a nice mix of own designed and imported products from Central America and Asia. Kitsch Kitchen is known for its beautiful, colorful prints. Why not take a look at Kitsch Kitchen's other items such as colorful bags, panniers, storage tins, and umbrellas!


text:
A Love of Music from the Very Beginning
Harlow Alexander, This Year's Shannon Kelly Kane scholarship Recipient
By Lisa Ferber
This article first appeared in the October 2018 issue of Teaching Music magazine.
For Harlow Alexander, music is definitely in her genes. The Pennsylvania native, Marywood University senior, and this year's Shannon Kelly Kane scholarship recipient grew up attending concerts with her father, Bret Alexander, a founding member of the rock band The Badlees. "My love of music started from the beginning," she said. "Going to gigs with my dad and traveling with him, and I'd help on the road, and he's teaching me to unwrap wires. Seeing live music and just going with him to other performances made me feel like I wanted to play music. When I was in fourth grade, I thought, 'I'm joining the school band.'"
Harlow Alexander Senior, Marywood University, Scranton, Pennsylvania. Photo: Ashlee Wilcox Photography, ashleewilcoxphotography.com
Alexander—who is currently president of the Pennsylvania Collegiate Music Educators Association—plays in a sax quartet at her Scranton-based school, as well as in the university's jazz band, wind ensemble, and wind symphony. Unlike her dad, however, this music education major found her soul in classical music. She's currently enjoying works by the composer David Maslanka.
"It comes down to what you're passionate about."
"The colors he creates with his works—I don't think I've experienced it playing anything else. Listening to the other people playing around me, you're just emotionally overwhelmed." And Alexander knows a thing or two about color: This NAfME member paints and draws, and she had been on the path to teach art, but when she was in her senior year of high school, she knew that this wasn't right for her. "It comes down to what you're passionate about. My marching band had very long rehearsals, and I was so dedicated, and when I tried to work as hard on art as I did on music, I thought, 'I can't see myself trying to teach this.'" Alexander notes that, when she told her English teacher that she didn't see herself teaching art and being happy, the teacher responded, "You'll know, and you'll feel right."
Harlow Alexander at the 2018 NAfME Collegiate Advocacy Summit in Reston, Virginia. Photo: Ashlee Wilcox Photography, ashleewilcoxphotography.com
Alexander says, "I remember the exact moment when I thought, 'Oh, my goodness, I need to go teach music.'" She was in a senior seminar for marching band, and band camp was over and summer was over. "And I thought, 'This is the last year that I'm going to get to do this.' There was a poster for Bloomsburg University, and it said, 'Come down for performing arts day,' and there was a lightbulb moment. I thought, 'I could do this for a living.'"
Harlow Alexander, Shannon Would, and Quinn Roberts (L to R) on NAfME Hill Day 2018 in Washington, D.C. Photo: Clarissa Budd.
Alexander would like to work as a band director in a school district. "From high school to college, I think it was the atmosphere that got me into music education. That atmosphere was created at marching band. The team work and the discipline and working toward one's goals. Doing what you love with the people that you love is an amazing thing."
NAfME President Kathleen D. Sanz presents Harlow Alexander the 2018 Shannon Kelly Kane scholarship award. Photo: Ashlee Wilcox Photography, ashleewilcoxphotography.com
2018 NAfME Collegiate Recognition Awards
Collegiate Professional Achievement Award Recipients
Jenae Maley, University of Central Missouri, Warrensburg, Missouri
Lindsey Streeter, Western Michigan University, Kalamazoo, Michigan
Harlow Alexander, Marywood University, Scranton, Pennsylvania
Chapter of Excellence Award Recipients
Recruitment: University of Central Missouri, Warrensburg, Missouri
Service: Lynchburg College, Lynchburg, Virginia
Professional Development: Indiana University, Bloomington, Indiana
Advocacy: University of Miami, Miami, Florida
Music Program: Marywood University, Scranton, Pennsylvania
Shannon Kelly Kane Scholarship Recipient
Learn more about Collegiate NAfME membership and join today.
Catherina Hurlburt, Marketing Communications Manager. October 30, 2018. © National Association for Music Education (NAfME.org)
Tags: Collegiate, jazz, music education major, Shannon Kelly Kane scholarship


text:
Men, women and plenty of children disembarked in Malta from the migrant rescue ship Aquarius on Wednesday afternoon, and the government announced a few hours later that Italy had agreed to join five other EU countries which have agreed to share them.
The ship's arrival in Malta marked the end of a five-day saga which saw it denied entry by several Mediterranean states.
Loud cheers from people aboard could be heard as the vessel made its way down the Grand Harbour to Senglea's Boilers Wharf, where it berthed across the creek from a luxury cruise ship.
Police and Armed Forces of Malta personnel were on hand to oversee the disembarkation process and take the 141 migrants rescued by the Aquarius to be registered and medically screened.
Members of the right-wing group Moviment Patrijotti Maltin unfurled a banner reading "Stop Human Trafficking" as rescued people prepared to disembark. Right next to them, crew members of another rescue vessel, the MV Lifeline, held up a banner of their own.
"Everyone has a right to life," the banner said.
According to Doctors without Borders (MSF), more than half the people on board, 73, are minors, with the vast majority unaccompanied by a parent or guardian. Most are "chronically undernourished", MSF said in a tweet. Some of the rescued children told crew members they had been kidnapped in Libya.
The claimed nationalities of the immigrants are Bangladesh, Cameroon, Ghana, Ivory Coast, Nigeria, Senegal, Togo, Egypt, Eritrea, Morocco and Somalia.
Some of the migrants waved as they were taken off the ship, one by one. And one of them got a special send-off, with members of the crew singing Happy Birthday to him.
The rescued migrants will be taken to a reception centre in Marsa. From there, they will be relocated to France, Germany, Luxembourg, Spain or Portugal, with those five EU member states having agreed to share responsibility for the rescued people.
The Maltese government later announced that Italy had also asked to participate in the initiative.
Aid NGOs including MSF welcomed the deal, though they warned that the ad hoc solution was no panacea.
A woman aboard the Aquarius looks out as the ship approaches Malta. Photo: Reuters
"Long-term sustainable solutions that address the humanitarian crisis on the central Mediterranean are still desperately needed," MSF said.
The 141 people aboard the Aquarius were rescued in two separate missions carried out last Friday. Crew had subsequently contacted authorities in Italy, Malta, Libya and Tunisia.
Italy's hard-line government was the most vocally opposed to allowing the ship to enter, with Home Affairs Minister Matteo Salvini saying ""It can go where it wants, not in Italy!"
Rescued people cheer as they approach Malta. Photo: Jonathan Borg
Rescue ships blocked
The Aquarius is one of the last remaining vessels conducting search and rescue missions in the central Mediterranean, with Italy having shut its ports to NGO ships in June and Malta having denied such vessels permission to leave its ports, citing concerns about ship registration anomalies.
The MV Lifeline, whose crew was on hand to welcome the Aquarius as it reached Malta, is among the vessels which has been blocked.
With the 141 people aboard the ship brought to safety, attention will now shift to the Aquarius' fate. International media has reported that the vessel's flag state, Gibraltar, has moved to strip it of its registration, on similar grounds to those Maltese authorities cited when blocking the Lifeline, another NGO-led rescue vessel.
A banner unfurled by Lifeline crew members. Photo: Jonathan Borg
According to the Gibraltar Maritime Administration, the Aquarius was registered as a "survey vessel" and was not authorised to conduct search and rescue operations. It will now revert to its "underlying owner", Germany, the GMA said.
Sources within the Maltese government declined to enter into details when asked about their plans for the ship and simply said that the vessel's future was uncertain.
Sarah Carabott


Available in any size, shape, or color combination.
Original Art by B. Coole Available with or without numbers. The 6 sided die is available with dots or numerals.
The sizes less than 2.5″ work better without numbers.


text:
We are back! 123Movies new domain is ww1.123movies1.com Watch, Share and Enjoy!
Street Outlaws: Memphis Season 4 Episode 10
Serie: Street Outlaws: Memphis
Other 123Movies to Watch Series Online
Genre: Game-Show
A devoted woman makes the ultimate sacrifice for her boyfriend, only to learn that love doesn't always conquer all. Yoo Jeong (Hwang Jeong Eum) is a sweet, upbeat person who…
Alien News Desk
This weekly, half-hour topical animated series set in an extraterrestrial newsroom covers up-to-the-minute news and commentary about the universe's most baffling species – the inscrutable Humans of Planet Earth.
Genre: Animation, News, Talk
When CIA analyst Jack Ryan stumbles upon a suspicious series of bank transfers his search for answers pulls him from the safety of his desk job and catapults him into…
Genre: Action, Action & Adventure, Drama, Thriller, War & Politics
Robert Schlag, nicknamed "Beat", is a Berlin club promoter who lives for the excesses of sex, drugs and the city nightlife. His connections to the underworld lead the police to…
You Can't Do That on Television
You Can't Do That on Television is a Canadian television program that first aired locally in 1979 before airing internationally in 1981. It featured pre-teen and teenaged actors in a…
Ed Goodson, a forthright and opinionated dad, relishes expressing his unsolicited and often wildly politically incorrect observations to anyone within earshot. Nobody is immune from Ed's rants, including his sons,…
Wild West Alaska
Alaskasfinestweaponsonsale.FollowJimandKenontheiradventureselling,buyingandusingAlaskasweapons.
Mythbusters Jr.
Six of America's most talented kids get a chance to show off their amazing ingenuity and STEAM (Science, Technology, Engineering, Arts, and Math) skills as they tackle myths similar to…
Canadian version of the reality show in which budding entrepreneurs pitch their business ideas to a panel of venture capitalists in the hopes of securing business financing.
A gripping family drama and entrepreneurial fable, set in a post-war Paris fashion house. It exposes the grit behind the glamour of a rising business, spearheaded by two clashing brothers.
Genre: Drama, History, Romance
Watch movies online Free movies online 123Movies Putlocker WatchSeries FMovies


text:
Alex Shearer
Available titles include
Alex Shearer is a British novelist and scriptwriter. His 2003 novel The Speed of the Dark was shortlisted for the Guardian Children's Fiction Prize. The Greatest Store in the World was adapted into a television film by the BBC. His novel Bootleg was adapted for a television series by the BBC, and later adapted into manga and anime under its Japanese title Chocolate Underground.
Click here for Alex's full list of available titles


Our guardrail accident lawyers are fighting for victims and their families injured by defective, outdated, or improperly installed guardrails.
Accidents involving these dangerous guardrails can be incredibly tragic, and many find themselves asking, how could this happen?
Dangerous guardrail designs can spell tragedy for accident victims. Guardrails exist to soften the blow of cars that collide on highways and interstates. But when defective designs are in place, they can do the exact opposite – many victims find themselves injured in ways they never might have been, had the guardrail worked as intended. Learn more about the Trinity guardrail lawsuits.
Outdated guardrails also pose a major threat to motorists. As safety technology changes and develops, outdated materials and designs become more and more dangerous. When outdated guardrails remain in place, they're like ticking time bombs – one bad accident can end in catastrophe, simply because old technology hadn't yet been replaced.
Improperly installed guardrails are a form of negligence. As taxpayers, we expect our roads and highways to be safely maintained. But when a guardrail is improperly installed, motorists' lives are at risk – because of someone else's failure to do their job right.
Many victims injured by dangerous guardrails face catastrophic life-altering injuries. Most commonly, limbs such as arms and legs are lost. Very tragically, many are killed due to the guardrail piercing through their body.


text:
Tag: Beverly Hilton
Mad Men 4.3 – We're Going to Have to Smoke the Dress
August 9, 2010 / Bob Westal
Howdy Sterling Cooper Draper Pryce-heads. Will Harris, your usual "Mad Men" blogger, has found himself here in beautiful Southern California and ensconced at the Beverly Hilton, where — as you may have noticed from his numerous posts — he has been covering the twice-annual conclave of the Television Critics Association (TCA). Ironically, especially considering last year's Conrad Hilton storyline, the beautiful and very pricey Beverly Hilton does not, in fact, carry AMC and so the job has been left to yours truly.
Now, for some reason, whenever I sit in for Will on one of these posts, there's always something stressing me out. Tonight it's these weird twinges in my upper right teeth that I'm hoping are somehow normally associated with the new nightguard I've been trying out from the dentist and not an early warning sign of a toothy catastrophe of some sort. However, as Don Draper would no doubt remark over an Old Fashioned, we've all got our problems And so it is in spades for pretty much all the featured characters on tonight's episode, which takes place around the New Year's holiday of 1964-65.
As we begin, Joan Harris is visiting her affable gynecologist, who is concerned that she'll be able to have a baby when her and Dr. Greg are finally ready. The doctor is wondering what Joan is waiting for as most newlywed females as positively ancient as Joan is would be desperate to have a baby yesterday, or so it seems to the kindly doc. There is also the obliquely referred to issue of not one but two abortions. One of the procedures was apparently performed by doc, though abortion would remain illegal in New York until 1970. An earlier procedure was performed by a woman who claimed to be a midwife. This isn't great, but Joan got pregnant (and unpregnant) after that and besides, there's always the wise words of songwriters Jay Livingston and Ray Evans: "whatever will be, will be." (I need to remember that about my teeth.)
Then it's off to offices of SCDP where Don is planning a New Year's get away to Acapulco, which always seemed to be swinging bachelor destination of choice on sixties sitcoms. Speaking of said sitcoms, Harry Crane, now quite the show biz insider, notes a 24 hour L.A. lay over in Don's itinerary. Why not hang out at the legendary Brown Derby with Harry's new acquaintance, producer Bill Asher? It's not mentioned, but William Asher's new program in '64 was a sitcom called "Bewitched" starring Asher's then spouse, the highly underrated Elizabeth Montgomery, as a witch whose magic powers were often employed in helping her advertising executive husband land and retain new clients. Occasionally "Mad Men" has what I sometimes call "McMahon & Tate moments" after the firm on the show — usually when someone saves a presentation at the last second with a sudden inspiration. Don, naturally, will blow off that Asher meeting. This trip is all about freedom, after all.
External Entertainment, External TV, Mad Men, Reviews, TV, TV Dramas
Beverly HiltonConrad HiltonDick WhitmanDon DraperGreg HarrisJared HarrisJoan HarrisJon HammJonathan AbrahamsLane PryceMad Men blogMan Men Season 4Matthew WeinerSam PageSterling Cooper Draper Pryce


Aspers World. It's our program that rewards you for being loyal to us and personalises your Aspers Casino experience.
Aspers World is all about introducing you to less earning, more winning. We like to reward you for being part of our world, so we've put together a range of benefits for you to enjoy when you're at an Aspers Casino or The Casino MK.
Your Aspers World tier depends on your level of play within the casino. You'll start off as a Voyager when you join.
Your tier level will change as your visits and play at the casino increase. The tiers that you could reach are Gold and VIP. Make sure you use your Aspers World Card at every opportunity within the casino to increase your chances of changing tier.
Aspers World cards can be used on all slot machines, electronic games and tables games in all of our casinos. You should insert your card into the card holder on the machine or hand it over to the croupier on the table you are playing on.
You can also use your card at our bars and restaurants to claim discounts. Simply ask your server about the Aspers World offers available to you.
As well as offers within the casinos, as an Aspers World member, you can take advantage of discounts with our partners.
You'll get 50% off entry when you show your Aspers World card at the entrance to Port Lympne Reserve and Howletts Wild Animal Park, plus you can get 12% off at Holiday Inn Westfield Stratford City, when you book a room online.
Each time you use your Aspers World card in selected gaming products, you'll collect Freeplay Xtra points.
You can spend these on slot or electronics machines and in selected bars and restaurants throughout our venues. Speak to a member of the team to find out more.
Visit our Guest Services desk at any Aspers Casino or The Casino MK. Remember to bring a valid form of photo ID with you to register.


For more information and related documents please click on the relevant tender below.
Choice Housing Ireland Ltd works with a diverse range of suppliers who help support the Associations mission statement "to enrich lives through great homes and services".
We have unique and demanding needs that evolve rapidly.
To help support our business operations we work with a rich diversity of suppliers. This includes suppliers of all types and sizes at local and national level.
When selecting who we work with we want to be transparent throughout the process and also demonstrate value for money. As an ethical organisation we want our suppliers to reflect our values and help us achieve our corporate social responsibility objectives.
The need to demonstrate value for money is central to our procurement strategy. We work with our suppliers to deliver contracts which are robust, fit for purpose and maximise value for money for the Association. We also strive to maximise the efficiency and effectiveness of our buying and sourcing solutions.
Choice Housing Ireland s Procurement team have embedded electronic tendering in line with current best practice.
The eProcurement system used by Choice is utilised by almost all Public Sector organisations throughout Northern Ireland – eTendersNI.
Potential suppliers are advised to register on eTendersNI and opt for as many relevant CPV (common procurement vocabulary) codes as possible. eTendersNI will email notifications about current opportunities to suppliers based on their CPV profiles.
Full guidance for suppliers is available through the eTendersNI website, however, any queries about registering on eTendersNI or using the system can be directed to the eTendersNI helpdesk on 0800 240 4545 or email ni-eproc-helpdesk@eurodyn.com.
In accordance with current guidance and regulations, for above EU Threshold procurements, the Association will award contracts on the basis of the Most Economical Advantageous Tender (MEAT).
These contracts will be advertised on eTendersNI and the Official Journal of the European Union.
For the majority of Construction Projects below EU Threshold the Association currently operates a Procurement Strategy for its Construction Work and Services in accordance with the Simplified Approach to Procurements Over £30K and Under EU Thresholds as Procurement Guidance Note (PGN) 05/12.
For non construction projects below EU Threshold the Association will adopt two procurement strategies. Below £30k will be either advertised via E Tenders or for specialized requirements invite a select list of suitably qualified suppliers to tender. All projects with an estimated value over £30k will be advertised via e Tenders NI.
Supplier selection is based on overall value for money to ensure the most economically advantageous contracts to Choice and surety of supply. There are a number of other criteria we evaluate including quality, reliability, safety, service and maintenance.
Potential suppliers must demonstrate their financial, commercial and technical capability to meet our contractual requirements. We also look for a clear demonstration of commitment to corporate social responsibility where appropriate.


text:
Kanye West & Drake's 'Free Larry Hoover' Concert To Stream On Amazon Prime
Josh Sanchez | Dec 8, 2021 9:45 am
The Kanye West and Drake benefit concert on Thursday, December 9 will now be available to stream online.
Late Tuesday night, it was announced that the "Free Larry Hoover" concert will stream live from the Memorial Coliseum in Los Angeles, California on Amazon Prime in more than 240 countries worldwide.
The concert — which is the first concert headlined by Ye in five years — will begin streaming at 11:00 p.m. ET.
Ye and Drake are joining forces and we've got your exclusive access. The monumental #FreeLarryHoover show will be free to stream globally on Amazon. #KanyeDrakeLivehttps://t.co/41feTihKXR pic.twitter.com/2a5Z8HGkEW
— Amazon Music (@amazonmusic) December 8, 2021
"Kanye and Drake have spent their careers pushing boundaries and defining culture, and we're excited to give fans around the world a front row seat to this concert," said Tim Hinshaw, head of hip-hop and R&B, Amazon Music, in a statement. "We have made Amazon Music and Prime Video destinations where artists can make their most ambitious ideas a reality—this concert is just the latest example."
The concert will also be airing in select IMAX theaters.
J. Prince has played an important part in bringing Ye and Drake together for the concert which hopes to bring awareness to prison reform.
"Through my work with Larry Hoover and his family, I've really had my eyes opened to the plight of incarcerated people in this country, and I hope fans of Ye and Drake will take the time to do the same," he said.
Will you be watching?
Survivor 41 Live Stream: How To Watch Season 41, Episode 12 Online
Entertainment,MusicDrake,Entertainment,Kanye West,Music,News


L'evinia is a range of high quality, mass-market fragrances and toiletries for the young, sophisticated and elegant female. It delivers a sophisticated, lingering scent to make a woman feel in control, attractive, confident and appealing. With involvement across a wide variety of categories, the local market has achieved key success in the Talc and Lotions trade.
Since their initial launch under the leadership of strong UAE distribution, L'evinia are now broadly associated with premium ingredients and affordability overall.
Initially a trial product in the UAE it has grown to rival some of the biggest talc and lotion brands in the region.
Hassan Mukhtar & Brothers are proud to develop their strong record further with premium toiletry brands.