param
(
    [switch]$multibox,
    [Parameter(Mandatory = $false)]
    [string]$relatedFilesDir,
    [Parameter(Mandatory = $false)]
    [string]$targetDirectory,
    [Parameter(Mandatory = $false)]
    [string]$deploymentDir,
    [Parameter(Mandatory = $false, HelpMessage = "The path to the directory in which to write log files.")]
    [string]$LogDir,
    [Parameter(Mandatory = $false, HelpMessage = "Indicate that this is being run in a Service Fabric context.")]
    [switch]$useServiceFabric = $false,
    [Parameter(Mandatory = $false)]
    [string]$webroot,
    [Parameter(Mandatory = $false)]
    [string]$aosPackageDirectory,
    [Parameter(Mandatory = $false)]
    [string]$sourcePackageDirectory,
    [Parameter(Mandatory = $false, HelpMessage = "Indicate that this is being run on a staging environment.")]
    [switch]$useStaging,
    [Parameter(Mandatory = $false)]
    [string]$tempWorkFolder = ""
)

$Global:installedPackages = @()

function GenerateSymLinkNgen([string]$webroot, [string]$metadataPackagePath)
{
    if ($useServiceFabric)
    {
        $DeveloperBox = $false
    }
    else
    {
        $DeveloperBox = Get-DevToolsInstalled
    }

    if (!$DeveloperBox)
    {
        Write-Output "Updating Symlink and Ngen Assemblies..."
        $datetime = Get-Date -Format "MMddyyyyhhmmss"
        $SymLinkNgenLog = Join-Path -Path $LogDir -ChildPath "update_SymLink_NgenAssemblies.log"
        $argumentList = '–webroot:"$webroot" –packagedir:"$metadataPackagePath" –log:"$($SymLinkNgenLog)"'

        $NgenoutPutLog = Join-Path -Path $LogDir -ChildPath "update_NgenOutput_$datetime.log"

        if (!(Test-Path -Path $NgenoutPutLog))
        {
            New-Item -ItemType File -Path $NgenoutPutLog -Force | Out-Null
        }

        Invoke-Expression "$metadataPackagePath\bin\CreateSymLinkAndNgenAssemblies.ps1 $argumentList" >> $NgenoutPutLog
    }
}

function UpdateAdditionalFiles([string]$webRoot, [string]$packageDir)
{
    $directorys = Get-ChildItem $packageDir -Directory
    foreach ($moduleName in $directorys)
    {
        $modulePath = Join-Path $packageDir $moduleName
        $additionalFilesDir = Join-Path $modulePath "AdditionalFiles"

        if (Test-Path $additionalFilesDir)
        {
            Write-log "Processing additional files for '$moduleName' "
            $filelocationsfile = Join-Path "$modulePath" "FileLocations.xml"
            if (Test-Path "$filelocationsfile")
            {
                [System.Xml.XmlDocument] $xd = New-Object System.Xml.XmlDocument
                $xd.Load($filelocationsfile)
                $files = $xd.SelectNodes("//AdditionalFiles/File")
                foreach ($file in $files)
                {
                    $assembly = [System.IO.Path]::GetFileName($file.Source)
                    $destination = $file.Destination
                    $relativepath = $file.RelativePath
                    $fullassemblypath = Join-Path "$modulePath" "AdditionalFiles\$assembly"

                    # the reason why we need to check for IsNullorEmpty() for the parameters is because the c:\pakages\bin
                    # comes from both the platform and app side. If the app bin package gets installed first
                    # it will leave a FileLocations.xml file at c:\packages\bin which will be processed by the
                    # platform bin package when it gets installed. We want to ensure that we do not throw an exception
                    # even if we don't find the correct set of parameters being passed from the calling function.
                    switch ($destination)
                    {
                        "AOSWeb" #enum for AOS webroot
                        {
                            $target = Join-Path "$webRoot" "$relativepath"
                        }

                        "PackageBin" #enum for \packages\bin\<<relativepath>>
                        {
                            if (-not [string]::IsNullOrEmpty($packageDir))
                            {
                                $target = Join-Path "$packageDir" "bin"
                                # Assemblies like BPExtensions have relativepath configured in FileLocations.xml. Hence considering relativepath for PackageBin similiar to how it is done in Copy-Files.
                                if (-not [string]::IsNullOrEmpty(($relativepath)))
                                {
                                    $target = join-path "$target" "$relativepath"
                                }
                            }
                        }

                        "ModuleBin" #enum for \<<modulename>>\bin
                        {
                            $target = Join-Path "$modulePath" "bin"
                        }

                        "PackageDir" #enum for \packages\<<relativepath>>
                        {
                            if (-not [string]::IsNullOrEmpty($packageDir))
                            {
                                $target = Join-Path "$packageDir" "$relativepath"
                            }
                        }
                    }

                    if ((Test-Path "$fullassemblypath") -and (-not [string]::IsNullOrEmpty($target)))
                    {
                        if (!(Test-Path "$target"))
                        {
                            Write-log "Creating target directory '$target'"
                            New-Item -Path "$target" -ItemType "directory" -Force | Out-Null
                        }

                        $targetfile = Join-Path "$target" $assembly
                        Write-log "Copying '$fullassemblypath' to '$targetfile'"
                        Copy-Item -path:"$fullassemblypath" -destination:"$targetfile" -Force
                    }
                }
            }

            Write-log "Removing '$additionalFilesDir'..."
            Remove-Item -Path $additionalFilesDir -Recurse -Force | Out-Null
        }
    }
}

function Update-PackageReferenceFile([string]$metadataPath, [string]$packageZipPath, [string]$tempdir)
{
    $ErrorActionPreference = "stop"

    $7zip = Join-Path -Path $env:SystemDrive -ChildPath "DynamicsTools\7za.exe"
    $temppackagesdir = Join-Path -Path $tempdir -ChildPath "temp_$(New-Guid)"

    if (Test-Path -Path $packageZipPath)
    {
        $zipFileNoExt = [System.IO.Path]::GetFileNameWithoutExtension($packageZipPath)
        $updateRefLog = Join-Path -Path $LogDir -ChildPath "install-$zipFileNoExt-$datetime.log"
        $unzipLogName = "install-$zipFileNoExt-$datetime-unzip.log"
        $unzipLog = Join-Path -Path $LogDir -ChildPath $unzipLogName

        $start = (Get-Date).ToUniversalTime()
        ("[{0}] Begin: Updating references from '{1}'" -f $start.ToString("o"), $packageZipPath) >> $updateRefLog

        if (!(Test-Path -Path $temppackagesdir))
        {
            New-Item -Path $temppackagesdir -ItemType directory -Force | Out-Null
        }

        "Unzipping $packageZipPath to $temppackagesdir..."  >> $updateRefLog
        $zip = Start-Process $7zip -ArgumentList "x $packageZipPath -o$temppackagesdir -y -mmt" -Wait -WindowStyle Hidden -PassThru -RedirectStandardOutput $unzipLog

        if ($zip.ExitCode -ne "0")
        {
            "7zip failed to unzip $packageZipPath. See '$unzipLogName' for details." >> $updateRefLog
            throw "7Zip failed to extract dynamics packages reference file."
        }

        $directories = Get-ChildItem -Path $temppackagesdir -Directory
        foreach ($directory in $directories)
        {
            $TargetReferenceUpdateDirectory = Join-Path -Path $metadataPath -ChildPath $directory.Name
            if (Test-Path -Path $TargetReferenceUpdateDirectory)
            {
                "Copying '$($directory.FullName)' to '$TargetReferenceUpdateDirectory'..."  >> $updateRefLog
                Copy-Item -Path ([IO.Path]::Combine($directory.FullName, "*")) -Destination $TargetReferenceUpdateDirectory -Force -Recurse
            }
        }

        if (Test-Path -Path $temppackagesdir)
        {
            "Removing temp directory '$temppackagesdir'..." >> $updateRefLog
            Remove-Item -Path $temppackagesdir -Recurse -Force
        }

        $end = (Get-Date).ToUniversalTime()
        ("[{0}] End: Updating references from '{1}'" -f $end.ToString("o"), $packageZipPath) >> $updateRefLog
    }
}

function Install-Package([string]$packageName, [string]$metadataPath, [string]$source, [string]$log)
{
    $ErrorActionPreference = "stop"

    $dynamicstools = "DynamicsTools"
    $installationrecords = Join-Path $metadataPath "InstallationRecords"
    $packageinstallationrecord = Join-Path $installationrecords $packageName

    $nuget = Join-Path $env:SystemDrive "$dynamicstools\nuget.exe"

    "Removing package installation record $packageinstallationrecord.*" >> $log
    Get-ChildItem -path "$installationrecords" -filter "$packageName.*" | Remove-Item -force -recurse

    "Unpacking the Dynamics packages to $installationrecords" >> $log

    "Running command: $nuget install -OutputDirectory `"$installationrecords`" $packageName -Source $source" >> $log
    if ([System.Version]([System.Diagnostics.FileVersionInfo]::GetVersionInfo($nuget).FileVersion) -ge [System.Version]"2.9.0.0")
    {
        & $nuget install -OutputDirectory "$installationrecords" $packageName -Source $source -DependencyVersion highest #nuget version > 2.8 change behaviour and add a new switch to set it back
    }
    else
    {
        & $nuget install -OutputDirectory "$installationrecords" $packageName -Source $source
    }
    # check the last exit code and decide if the package(s) were installed correctly
    if ($LASTEXITCODE -ne 0)
    {
        Throw "Something went wrong when installing the Dynamics package '$packageName'. Make sure the package name is correct and that it exists at the source directory '$source'."
    }

}

function Install-ZipPackage ([string]$clickoncePath, [string]$metadataPath, [string]$frameworkPath, [string]$packageZipPath, [string]$source, [string]$webroot, [string]$log)
{
    $ErrorActionPreference = "stop"

    #install package
    $arguments = 'clickOnceInstallPath="{0}";metadataInstallPath="{1}";frameworkInstallPath="{2}";packageZipDrop="{3}";webroot="{4}";log="{5}"' -f $clickoncePath, $metadataPath, $frameworkPath, $packageZipPath, $webroot, $log
    $arguments
    $env:DynamicsPackageParameters = $arguments
    $dynamicstools = "DynamicsTools"
    $installationrecords = Join-Path $metadataPath "InstallationRecords"
    $packageinstallationrecord = Join-Path $installationrecords $packageName

    # iterate over every installed package and run the custom powershell script
    $packagesdir = [System.IO.Directory]::EnumerateDirectories($installationrecords, "*", [System.IO.SearchOption]::TopDirectoryOnly)
    foreach ($dir in $packagesdir)
    {
        $currentpackagename = [System.IO.Path]::GetFileName($dir)
        $toolsdir = Join-Path $dir "tools"
        $installscript = Join-Path $toolsdir "installpackage.ps1"
        if (Test-Path $installscript)
        {
            $Global:installedPackages += $currentpackagename

        }
    }
    Parallel-Install -packagesName:$Global:installedPackages -installationrecorddir:$installationrecords
}

function Get-PackageName([string] $fileName)
{
    return $fileName.Split("-")[1]
}

function Remove-MetadataSourceDirectory([string] $packageName, [string] $packageInstallPath)
{
    $basePackageName = Get-PackageName $packageName

    if ($packageName.EndsWith('-compile'))
    {
        $packageInstallPath = Join-Path $packageInstallPath $basePackageName
        $packageInstallPath = Join-Path $packageInstallPath 'XppMetadata'
        if (Test-Path $packageInstallPath)
        {
            #powershell bug - Remove-Item comlet doesn't implement -Recurse correctly
            #Remove-Item $packageInstallPath -Force -Recurse
            Get-ChildItem -path "$packageInstallPath" -force -recurse | Remove-Item -force -recurse
        }
    }
    if ($packageName.EndsWith('-develop'))
    {
        $packageInstallPath = Join-Path $packageInstallPath $basePackageName
        $packageInstallPath = Join-Path $packageInstallPath $basePackageName
        if (Test-Path $packageInstallPath)
        {
            #powershell bug - Remove-Item comlet doesn't implement -Recurse correctly
            #Remove-Item $packageInstallPath -Force -Recurse
            Get-ChildItem -path "$packageInstallPath" -force -recurse | Remove-Item -force -recurse
        }
    }
}

function Remove-SourceDirectory([string] $packageName, [string] $packageInstallPath)
{
    $packageDir = Join-Path $packageInstallPath $packageName
    if (Test-path $packageDir\Descriptor)
    {
        $packageDescriptorXmls = Get-ChildItem $packageDir\Descriptor -filter "*.xml"
        # Delete all folders with matching names with the xml filenames in descriptor
        foreach ($packageDescriptorXml in $packageDescriptorXmls)
        {
            $sourceDirectory = Join-Path $packageDir $packageDescriptorXml.BaseName
            if (Test-path $sourceDirectory)
            {
                Get-ChildItem -path "$sourceDirectory" -force -recurse | Remove-Item -force -recurse
            }
        }
    }
}

function Parallel-Install([string[]] $packagesName, [string] $installationrecorddir)
{
    $ErrorActionPreference = "stop"
    foreach ($pkg in $packagesName)
    {
        $dir = Join-Path $installationrecorddir $pkg
        $toolsdir = Join-Path $dir "tools"
        $installscript = Join-Path $toolsdir "installpackage.ps1"
        if (Test-Path $installscript)
        {
            Write-Output "Running script '$installScript'"
            & $installscript
            Move-Item $installscript ($installscript + ".executed") -Force
        }

    }
}

$ErrorActionPreference = "Stop"
if (!$useServiceFabric)
{
    Import-Module WebAdministration
}

Import-Module "$PSScriptRoot\CommonRollbackUtilities.psm1" -ArgumentList $useServiceFabric -DisableNameChecking
Import-Module "$PSScriptRoot\AosEnvironmentUtilities.psm1" -ArgumentList $useServiceFabric -Force -DisableNameChecking

if (!$useServiceFabric)
{
    if (Test-Path "$($PSScriptRoot)\NonAdminDevToolsInterject.ps1")
    {
        & "$PSScriptRoot\NonAdminDevToolsInterject.ps1"
    }
}

if ($tempWorkFolder -ne "")
{
    $tempPackagesDir = $tempWorkFolder
}
else
{
    $tempPackagesDir = [System.IO.Path]::GetTempPath()
}

if ($useStaging)
{
    $webroot = Join-Path $(Get-AosServiceStagingPath) "webroot"
    $metadataPackagePath = Join-Path $(Get-AosServiceStagingPath) "PackagesLocalDirectory"
    $frameworkPackagePath = Join-Path $(Get-AosServiceStagingPath) "PackagesLocalDirectory"
    $sourcePath = [IO.Path]::Combine($(Split-Path -parent $PSScriptRoot), "Packages")
}
elseif ($useServiceFabric)
{
    $webroot = (Resolve-Path $webroot).ProviderPath
    $clickOncePackagePath = Join-Path $webroot "apps"
    $sourcePath = $sourcePackageDirectory
    $metadataPackagePath = $aosPackageDirectory
    $frameworkPackagePath = $aosPackageDirectory
    if ($tempWorkFolder -eq "")
    {
        $tempPackagesDir = $sourcePath
    }
}
else
{
    $webroot = Get-AosWebSitePhysicalPath
    $metadataPackagePath = $(Get-AOSPackageDirectory)
    $frameworkPackagePath = $(Get-AOSPackageDirectory)
    $sourcePath = [IO.Path]::Combine($(Split-Path -parent $PSScriptRoot), "Packages")
}

if (!$useServiceFabric)
{
    $clickOncePackagePath = $(Get-InfrastructureClickonceAppsDirectory)
    $clickOncePackagePath = [IO.Path]::Combine($webroot, $clickOncePackagePath)
}

$resourcePath = [IO.Path]::Combine($webroot, "Resources")
$packageZipDrop = [IO.Path]::Combine($sourcePath, "files")

if ((![string]::IsNullOrWhiteSpace($targetDirectory)) -and (Test-Path $targetDirectory))
{
    $metadataPackagePath = $targetDirectory
    $frameworkPackagePath = $targetDirectory
}

if ((![string]::IsNullOrWhiteSpace($deploymentDir)) -and (Test-Path $deploymentDir))
{
    if ($multibox)
    {
        $clickOncePackagePath = [IO.Path]::Combine($deploymentDir, "WebRoot\apps")
        $webroot = [IO.Path]::Combine($deploymentDir, "WebRoot")
        $resourcePath = [IO.Path]::Combine($deploymentDir, "WebRoot\Resources")
    }
    else
    {
        $clickOncePackagePath = [IO.Path]::Combine($deploymentDir, "DObind\Packages\Cloud\AosWebApplication\AosWebApplication.csx\roles\AosWeb\approot\apps")
        $webroot = [IO.Path]::Combine($deploymentDir, "DObind\Packages\Cloud\AosWebApplication\AosWebApplication.csx\roles\AosWeb\approot")
        $resourcePath = [IO.Path]::Combine($deploymentDir, "DObind\Packages\Cloud\AosWebApplication\AosWebApplication.csx\roles\AosWeb\approot\Resources")
    }
}

if ((![string]::IsNullOrWhiteSpace($relatedFilesDir)) -and (Test-Path $relatedFilesDir))
{
    $sourcePath = $relatedFilesDir
    $packageZipDrop = [IO.Path]::Combine($relatedFilesDir, "files")
}

$datetime = Get-Date -Format "MMddyyyyhhmmss"

if (!$LogDir)
{
    $LogDir = $PSScriptRoot
}

$log = Join-Path -Path $LogDir -ChildPath "install-AXpackages_$datetime.log"
if (!(Test-Path -Path $log))
{
    New-Item -Path $log -ItemType File -Force | Out-Null
}

$innerlog = Join-Path -Path $LogDir -ChildPath "update-AXpackages_$datetime.log"
if (!(Test-Path -Path $innerlog))
{
    New-Item -Path $innerlog -ItemType File -Force | Out-Null
}


$startdatetime = Get-Date
"*******************************************************" >> $log
"** Starting the package deployment at $startdatetime **" >> $log
"*******************************************************" >> $log

$installationrecords = Join-Path -Path $metadataPackagePath -ChildPath "InstallationRecords"

if (!(Test-Path -Path $installationrecords))
{
    "Creating installation record directory '$($installationrecords)' to keep the installation history." >> $log
    New-Item -Path $installationrecords -ItemType Directory -Force | Out-Null
}
else
{
    # clean up prior nuget installation of the previous package that fail to install
    $packagesdir = [System.IO.Directory]::EnumerateDirectories($installationrecords, "*", [System.IO.SearchOption]::TopDirectoryOnly)
    foreach ($dir in $packagesdir)
    {
        $toolsdir = Join-Path -Path $dir -ChildPath "tools"
        $installscript = Join-Path -Path $toolsdir -ChildPath "installpackage.ps1"
        if (Test-Path -Path $installscript)
        {
            Move-Item -Path $installscript -Destination $($installscript + ".executed") -Force
        }
    }
}

if ($useServiceFabric)
{
    $DeveloperBox = $false
}
else
{
    $DeveloperBox = Get-DevToolsInstalled
}

#Check if this is a binary update package for RunOne environment
#Clean up source directories for Microsoft-owned module packages to support x++ refactoring
if(Get-IsBinaryPackageTypeFromPackage -and Get-IsAppSealed)
{
    if ($DeveloperBox -eq $true)
    {
        # Get the list of currently installed packages based on installation records
        $installationrecords = Join-Path $metadataPackagePath "InstallationRecords"
        $nugetPackageFiles = Get-ChildItem -Path:$installationrecords -recurse  -filter "*-develop.*.nupkg"
        # Get the list of Microsoft-owned app and plat packages
        $applicationPackageNames = Get-PackageNamesFromDLL -productInfoDLL "bin\ProductInfo\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Application.dll"
        $platformPackageNames = Get-PackageNamesFromDLL -productInfoDLL "bin\ProductInfo\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Platform.dll"

        if (($applicationPackageNames.count -gt 0) -or ($platformPackageNames.count -gt 0))
        {
            foreach ($nugetPackageFile in $nugetPackageFiles)
            {
                $packageName = Get-PackageName -fileName $nugetPackageFile.BaseName
                # Check whether package is a Microsoft-owned application package
                if((Get-IsModulePartOfApplicationAsBinary -PackageNugetFilePath $nugetPackageFile.FullName) -and ($applicationPackageNames -contains $packageName))
                {
                    "Removing source directories for package: $packageName" >> $log
                    Remove-SourceDirectory -packageName $packageName -packageInstallPath $metadataPackagePath

                    "Removing package installation record for package: $packageName-develop" >> $log
                    Get-ChildItem -path "$installationrecords" -filter "dynamicsax-$packageName-develop.*" | Remove-Item -force -recurse
                }
                # Check whether package is a Microsoft-owned platform package
                elseif((Get-IsModulePartOfPlatformAsBinary -packageNugetFile $nugetPackageFile.FullName) -and ($platformPackageNames -contains $packageName))
                {
                    "Removing source directories for package: $packageName" >> $log
                    Remove-SourceDirectory -packageName $packageName -packageInstallPath $metadataPackagePath

                    "Removing package installation record for package: $packageName-develop" >> $log
                    Get-ChildItem -path "$installationrecords" -filter "dynamicsax-$packageName-develop.*" | Remove-Item -force -recurse
                }
            }
        }
    }
}

#Check if this is a platform update package base on existence of the config file.
#if it's platformUpdate3 or later, also perform the meta package installation for platform binarys
if ((Test-Path -Path "$PSScriptRoot\PlatformUpdatePackages.Config") -or (Get-IsPlatformUpdate3OrLater -webroot:$webroot))
{
    if (Test-Path -Path $sourcePath)
    {
        [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
        if ($DeveloperBox -eq $true)
        {
            $PackageToInstall = "dynamicsax-meta-platform-development"
        }
        else
        {
            $PackageToInstall = "dynamicsax-meta-platform-runtime"
        }
        if (![string]::IsNullOrWhiteSpace($PackageToInstall))
        {
            $zipFile = Get-Item $sourcePath\$PackageToInstall*.nupkg
            if ($zipFile -eq $null)
            {
                #only throw error if it's a dedicated inplace upgrade package,
                #on any other package it's possible that the meta package doesn't existing thus no operation required
                if (Test-Path "$PSScriptRoot\PlatformUpdatePackages.Config")
                {
                    Throw "Unable to get package information"
                }

            }
            else
            {
                $PackFiles = [IO.Compression.ZipFile]::OpenRead($zipFile).Entries
                $PackageSpec = $PackFiles | Where-Object { ($_.Name -like '*.nuspec') }

                if (!($PackageSpec))
                {
                    Throw "Unable to get package information"
                }

                [System.Xml.XmlDocument] $xmlDoc = New-Object System.Xml.XmlDocument
                $XmlDoc.Load($PackageSpec.Open())

                $Dependencies = $xmlDoc.GetElementsByTagName('dependency').id

                if ($Dependencies.Contains("dynamicsax-systemhealth"))
                {
                    #Remove AxPulse due to the name change to SystemHealth in PlatUpdate3
                    $axPulsePath = Join-Path -Path $metadataPackagePath -ChildPath "axpulse"

                    if (Test-Path $axPulsePath)
                    {
                        Remove-Item $axPulsePath -Force -Recurse
                    }
                    if (Test-Path $installationrecords)
                    {
                        Get-ChildItem -path "$installationrecords" -filter "dynamicsax-axpulse.*" | Remove-Item -force -recurse
                    }
                }

                #Install all packages in meta-package definition
                forEach ($Package in $Dependencies)
                {
                    #if it's not appFall or later, install directory package from platform
                    #all other platform package specified in meta package will get installed
                    if (($(Get-PackageName $Package) -ne 'Directory') -or (!$(Get-IsAppFallOrLater -webroot:$webroot)))
                    {
                        "Removing package installation record $Package.*" >> $log
                        Get-ChildItem -path "$installationrecords" -filter "$Package.*" | Remove-Item -force -recurse

                        #Remove MetaData and Source Directories for the package before Installing
                        Remove-MetadataSourceDirectory -packageName $Package -packageInstallPath $metadataPackagePath
                    }
                }
                Install-Package -packageName:$PackageToInstall -metadataPath:$metadataPackagePath -source:$sourcePath -log:$log >> $innerlog
            }
        }
    }
}

#dependencyaos
#Install App packages if it is sealed
if ($(Get-IsAppSealed -webroot:$webroot ))
{
    if (Test-Path $sourcePath)
    {
        [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
        if ($useServiceFabric)
        {
            $DeveloperBox = $false
        }
        else
        {
            $DeveloperBox = Get-DevToolsInstalled
        }
        if ($DeveloperBox -eq $true)
        {
            $PackageToInstall = "dynamicsax-meta-application-development"
        }
        else
        {
            $PackageToInstall = "dynamicsax-meta-application-runtime"
        }
        if (![string]::IsNullOrWhiteSpace($PackageToInstall))
        {
            $zipFile = Get-Item $sourcePath\$PackageToInstall*.nupkg

            if ($zipFile -ne $null)
            {
                $PackFiles = [IO.Compression.ZipFile]::OpenRead($zipFile).Entries
                $PackageSpec = $PackFiles | Where-Object { ($_.Name -like "*.nuspec") }

                if (!($PackageSpec))
                {
                    Throw "Unable to get package information"
                }

                [System.Xml.XmlDocument] $xmlDoc = New-Object System.Xml.XmlDocument
                $XmlDoc.Load($PackageSpec.Open())

                $Dependencies = $xmlDoc.GetElementsByTagName('dependency').id

                #Install all packages in meta-package definition
                forEach ($Package in $Dependencies)
                {
                    "Removing package installation record $Package.*" >> $log
                    Get-ChildItem -path "$installationrecords" -filter "$Package.*" | Remove-Item -force -recurse

                    #Remove MetaData and Source Directories for the package before Installing
                    Remove-MetadataSourceDirectory -packageName $Package -packageInstallPath $metadataPackagePath
                }
                Install-Package -packageName:$PackageToInstall -metadataPath:$metadataPackagePath -source:$sourcePath -log:$log >> $innerlog
            }
        }
    }
}

#still need to perform the aot package installation that's not part of platform or app.
if (!(Test-Path "$PSScriptRoot\PlatformUpdatePackages.Config"))
{
    if (Test-Path $sourcePath)
    {
        $files = Get-ChildItem -Path:$sourcePath *.nupkg
        $customerPackages = @()
        
        foreach ($packageFile in $files)
        {
            $packageName = ($packageFile.BaseName).Split(".")[0]
        
            #if it's not platupdate3 or later, install all package
            #if it's platupdate3 or later, install all package that's not part of platform
            if ($(Get-IsModulePartOfPlatformAsBinary -packageNugetFile $packageFile.FullName))
            {
                if (!$(Get-IsPlatformUpdate3OrLater -webroot:$webroot))
                {
                    Install-Package -packageName:$packageName -metadataPath:$metadataPackagePath -source:$sourcePath -log:$log >> $innerlog
                }
            }
            # If app is not sealed, install all [Application Package]
            elseif (Get-IsModulePartOfApplicationAsBinary -PackageNugetFilePath $packageFile.FullName)
            {
                if (!$(Get-IsAppSealed -webroot:$webroot))
                {
                    Install-Package -packageName:$packageName -metadataPath:$metadataPackagePath -source:$sourcePath -log:$log >> $innerlog
                }
            }
            # Allow customer extensions
            else
            {
                # Remove the customer's packages from the installation folder prior to installing them.
                "Removing package installation record $packageName.*" >> $log
                Get-ChildItem -path "$installationrecords" -filter "$packageName.*" | Remove-Item -force -recurse
                $customerPackages += $packageName
            }
        }
        
        # Install the customer's packages.
        foreach($customerPackage in $customerPackages)
        {
            Install-Package -packageName:$customerPackage -metadataPath:$metadataPackagePath -source:$sourcePath -log:$log >> $innerlog
        }
        
    }
}

Install-ZipPackage -metadataPath:$metadataPackagePath -clickoncePath:$clickOncePackagePath -frameworkPath:$frameworkPackagePath -packageZipPath:$packageZipDrop -source:$sourcePath -webroot:$webroot -log:$log >> $innerlog

Write-Output "Updating Metadata Resources File."
$UpdateResourcesLog = Join-Path -Path $LogDir "Update_Resources_$datetime.log"
$ResourceConfig = @{"Common.BinDir" = $metadataPackagePath; "Infrastructure.WebRoot" = $webroot }
$ResourceBase64Config = ConvertTo-Json $ResourceConfig
$ResourceBase64Config = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($ResourceBase64Config))
$argumentList = '–config:"$ResourceBase64Config" –log:"$($UpdateResourcesLog)"'

$Resourceslog = Join-Path -Path $LogDir -ChildPath "Update_Resources_Output_$datetime.log"
if (!(Test-Path -Path $Resourceslog))
{
    New-Item -ItemType File -Path $Resourceslog -Force | Out-Null
}

Invoke-Expression "$PSScriptRoot\DeployResources.ps1 $argumentList" >> $Resourceslog

Write-Output "Updating Metadata Reference File."
Update-PackageReferenceFile -metadataPath:$metadataPackagePath -packageZipPath:$(Join-Path -Path $packageZipDrop -ChildPath "MetadataReferenceApp.zip") -tempdir:$tempPackagesDir
Update-PackageReferenceFile -metadataPath:$metadataPackagePath -packageZipPath:$(Join-Path -Path $packageZipDrop -ChildPath "MetadataReferencePlat.zip") -tempdir:$tempPackagesDir

Write-Output "Updating Additional Files."
UpdateAdditionalFiles -webRoot:$webroot -packageDir:$metadataPackagePath

if (!$useServiceFabric)
{
    try
    {
        $DeveloperBox = Get-DevToolsInstalled
        if (!$DeveloperBox)
        {
            if (Test-Path -Path "$PSScriptRoot\RemoveSymLinkAndNgenAssemblies.ps1")
            {
                Write-Output "Removing SymLink And NgenAssemblies..."
                Invoke-Expression "$PSScriptRoot\RemoveSymLinkAndNgenAssemblies.ps1 -useStaging:`$$($useStaging)"
                Write-Output "Removing SymLink And NgenAssemblies completed."
            }
        }
    }
    catch
    {
        Write-Output "Warning: Failed to remove SymLink And NgenAssemblies: $($_)"
        Write-Output "Generating SymLink And NgenAssemblies..."
        # Always generate symlink point to the non-staging folder of the AOS service.
        GenerateSymLinkNgen -webroot:$webroot -metadataPackagePath:$(Get-AOSPackageDirectory)
        Write-Output "Generating SymLink And NgenAssemblies completed."
    }

    try
    {
        $CommonBin = Get-CommonBinDir
        $AXInstallationInfoPath = Join-Path -Path $CommonBin -ChildPath "bin\Microsoft.Dynamics.AX.AXInstallationInfo.dll"

        # Using Add-Type which will auto load all referenced assemblies.
        Add-Type -Path $AXInstallationInfoPath

        Write-Output "Creating Metadata Module Installation Info..."
        [Microsoft.Dynamics.AX.AXInstallationInfo.AXInstallationInfo]::ScanMetadataModelInRuntimePackage($metadataPackagePath)
        Write-Output "Creating Metadata Module Installation Info completed."
    }
    catch
    {
        Write-Warning "Failed to create metadata module installation record: $($_)"
    }
}

$enddatetime = Get-Date
"******************************************************" >> $log
"** Completed the package deployment at $enddatetime **" >> $log
"******************************************************" >> $log
"" >> $log
$duration = $enddatetime - $startdatetime
"Package deployment duration:" >> $log
"$duration" >> $log

"" >> $log
"******************************************************" >> $log
"Packages installed in this session:" >> $log
"******************************************************" >> $log
foreach ($pkg in $Global:installedPackages)
{
    "$pkg" >> $log
}

""
"******************************************************"
"Packages installed in this session:"
"******************************************************"
foreach ($pkg in $Global:installedPackages)
{
    "$pkg"
}
""
"installation log file: $log"

# SIG # Begin signature block
# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCjf6ftHQPsy5qX
# CHzpBB8jLhOqxr9Fh9r1mQq/r0JeHKCCDYEwggX/MIID56ADAgECAhMzAAABh3IX
# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB
# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH
# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d
# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ
# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV
# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy
# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K
# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV
# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr
# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx
# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe
# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g
# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf
# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI
# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5
# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea
# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgS5/0tXK1
# lXB0L7ZvUJ9Fv50AQkXIkiaoNRwfloU5AzAwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
# BgkqhkiG9w0BAQEFAASCAQAlVoyRJigLL7QHA2+OGsPIDL6i2+J57oaYdm3IzH19
# frfmKPIL2cGxh86hCAw2ZQ2IuglRMpl+EIw8lmy9hRxo738sPOjMYwgjLXEj+LyE
# Q+BEJNPA91o1elW7KbRmeqp4uzaM6vSnhyetw/vo0zXlZZ0gb5Z7QQJdRE0vraw5
# 3NVFwttg7j2xTbtanpVpYpbRoiN0JcITqQDANcEmaMe0InsMjL5zqenRNKywAoWs
# z/g/svSzDufqm6IrB+a9Bq3IYmZ5n2qlmlDagbBb8wQlk7NHvDC5FNhqqX9kpNfk
# Ep0ojSERwgCCr9eQe60iYCVoimWu9DqdF4oq66Jk/JhooYIS8TCCEu0GCisGAQQB
# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME
# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB
# MDEwDQYJYIZIAWUDBAIBBQAEIIFV8EexuqToXOdpXYO1FnhYTgmqBArP9siXPm4V
# ZoL2AgZftBA+JroYEzIwMjAxMTE5MjAzNTQ3Ljk5MlowBIACAfSggdSkgdEwgc4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p
# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg
# VFNTIEVTTjpGODdBLUUzNzQtRDdCOTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABL7GnF3lWlBeHAAAA
# AAEvMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
# MB4XDTE5MTIxOTAxMTUwNloXDTIxMDMxNzAxMTUwNlowgc4xCzAJBgNVBAYTAlVT
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy
# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpGODdB
# LUUzNzQtRDdCOTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKh8VkvVIwXD8sn0zT2n
# EdyEZ9UNHY7ACbOZA4obAHvD1hauw9K1Z2lRWG+m8Ars9l35GoMXdPgshM3hZKQW
# fhrLnF9/GDZoilhc2LhMqNPXs06rAJ8YODB6i0Cg1CFCYnyOYvywXKY3xGJN09Dg
# PXWfczEm2P/a3rmrXMrK5EFc3ahxrC51c+UuAMKV9xJyzJVLShPwPBJl+CjdMDPJ
# f24DZXIYec3gCN2xean1DFCI0gaqJprMeL4Om1KY2AZMIgBPEkoY1N7AI5e7ybkI
# L8+Mz3inijb4rDTkXk86ztUwy4bdc1MyKe2j2odT+QIDA2+M8cMTIGlKn7EyD2NN
# XU8CAwEAAaOCARswggEXMB0GA1UdDgQWBBSml/VRpBNFkAMDiqcoqWi85j/qljAf
# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH
# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU
# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0
# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG
# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQB4q6ilv2SlGvJD/7dbfoIKZBO2i6YA
# wckw57TpCrt2+SAx2dcF7JvRMCPhLCSgqjyNcJRs40cEXPbLdzZMJHzcv73AF7L6
# mWZXg2aBjG1Sc5qM4jjE/nwIX+C6/odm5/asU4JIlFCuUZjzqdir18HkRVQve2Hw
# V0lCXHQs+V3m9DyyA9b6LSIk3GOFZu7F11Wyx/5dVXisPPTPwh9JXfMD9W173M1+
# ZZycmO03lUc4G1FilgpxWNdgWn/DO9ZhoW5yN6+BUddnJ4cCcCjcg8sB5rktPP8p
# VZAQ7aUqkAeqo+FuCkAUAdJRESCpR5wgSPtVvFPMjONE36DbKtfzkfiHMIIGcTCC
# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv
# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN
# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw
# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0
# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw
# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe
# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx
# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G
# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA
# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7
# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC
# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX
# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI
# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g
# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93
# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB
# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA
# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh
# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS
# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK
# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon
# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi
# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/
# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII
# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0
# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a
# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ
# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+
# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP
# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpG
# ODdBLUUzNzQtRDdCOTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
# dmljZaIjCgEBMAcGBSsOAwIaAxUAM/CZCUpclQ9qfr/r3y9osIIPSmSggYMwgYCk
# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
# AONhMWgwIhgPMjAyMDExMTkyMjAxMTJaGA8yMDIwMTEyMDIyMDExMlowdzA9Bgor
# BgEEAYRZCgQBMS8wLTAKAgUA42ExaAIBADAKAgEAAgImNQIB/zAHAgEAAgIRzzAK
# AgUA42KC6AIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB
# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAIHinWBltSvUTQV9
# XNAu+1Fbj68yZ3YDjn1XWzDYcJI/Hce9R4A4c6rwK42P/aWAb+Pbf73Xn8sG+vc5
# npinOSZQ5tnhvk6OWqqz7Bih1w/ISyAVSRKeXEmBC0fss+vTI6MdGPcaAmTolmDS
# jfSIdOxu1OzPCOrIJ/sAEx0Lu5QfMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
# bWUtU3RhbXAgUENBIDIwMTACEzMAAAEvsacXeVaUF4cAAAAAAS8wDQYJYIZIAWUD
# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B
# CQQxIgQgqwEzB0rqXPOuUGiDxJ24WpPFbjUf3xVzpM2UkOsiJCQwgfoGCyqGSIb3
# DQEJEAIvMYHqMIHnMIHkMIG9BCBC5RecGZvugnvVXg80zlrGv1uV35LNk+H9dBj3
# ChFPvTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB
# L7GnF3lWlBeHAAAAAAEvMCIEIHdQXcNtVf7iEalT1oSiiDfHEkHxikTjANgCtAH0
# bQbcMA0GCSqGSIb3DQEBCwUABIIBAI3fBI8Z8keR8KwWLQvNVhyc5nA4f/0T38Pg
# UXxz6gM8UHJEsn6lMjh59YdGV4YGJuwvUic82ckFRanrPja8o+4YJzjB52khtjAX
# lDy/jccGeruDM8qIu6RUeKKTUjwlZdW8LxsAEZfqd8pgh7uCHU9pOxotTkik8Vez
# sWEISOthM3yPB97K+w1f3CtjsO8vGhBR5EcxpCevI9TUwiNdcDk8+QqK8GNhxH/0
# TzCta7N9HpIFUgJaR4HbXcpCJvPS045qHyBPSmShRS53heZelNG5mOlwCpMFClhF
# nAp/sojLKVr5yMftODDCqtv5RV0wbSV03etHXoVW6cgepPTIoyM=
# SIG # End signature block
