function ProjectRetargeting-ShowErrorUponRetargeting {
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Assert that an error has been added to the error list window)

    $errorlist = Get-Errors

    Assert-AreEqual 1 $errorlist.Count

    $error = $errorlist[$errorlist.Count-1]

    Assert-AreEqual 'Some NuGet packages were installed using a target framework different from the current target framework and may need to be reinstalled. Visit http://docs.nuget.org/docs/workflows/reinstalling-packages for more information.  Packages affected: PackageTargetingNet40AndNet40Client' $error.Description
}

function ProjectRetargeting-ClearErrorUponCleanProject {
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Assert that an error has been added to the error list window)

    $errorlist = Get-Errors

    Assert-AreEqual 1 $errorlist.Count

    Clean-Project

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count
}

function ProjectRetargeting-ClearErrorUponCloseSolution {
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Assert that an error has been added to the error list window)

    $errorlist = Get-Errors

    Assert-AreEqual 1 $errorlist.Count

    Close-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count
}

function ProjectRetargeting-ClearErrorAndWarningRetargetBackToOriginalFramework {
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Assert that an error has been added to the error list window)

    $errorlist = Get-Errors

    Assert-AreEqual 1 $errorlist.Count

    # Change the framework of the project back to .NET 4.0 and verify that the error shown is cleared

    $p = Get-Project $projectName
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=4.0'

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    Build-Solution

    $warnings = Get-Warnings

    Assert-AreEqual 0 $warnings.Count
}

function ProjectRetargeting-ConvertBuildErrorToBuildWarningUponBuild {
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Assert that an error has been added to the error list window)

    $errorlist = Get-Errors

    Assert-AreEqual 1 $errorlist.Count

    # Build Solution now and verify that the error has been converted to a warning

    Build-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 1 $warnings.Count

    $warning = $warnings[$warnings.Count - 1]

    Assert-AreEqual 'Some NuGet packages were installed using a target framework different from the current target framework and may need to be reinstalled. Visit http://docs.nuget.org/docs/workflows/reinstalling-packages for more information.  Packages affected: PackageTargetingNet40AndNet40Client' $warning.Description
}

function ProjectRetargeting-ShowWarningOnCleanBuild
{
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Clean and Build the Solution again. And, verify that the warning is shown as expected)

    Clean-Project
    Build-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 1 $warnings.Count

    $warning = $warnings[$warnings.Count - 1]

    Assert-AreEqual 'Some NuGet packages were installed using a target framework different from the current target framework and may need to be reinstalled. Visit http://docs.nuget.org/docs/workflows/reinstalling-packages for more information.  Packages affected: PackageTargetingNet40AndNet40Client' $warning.Description
}

function ProjectRetargeting-ClearWarningUponCleanProject
{
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Verify that the warning is cleared upon cleaning solution)

    Build-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 1 $warnings.Count

    $warning = $warnings[$warnings.Count - 1]

    Clean-Project

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 0 $warnings.Count
}

function ProjectRetargeting-ClearWarningUponCloseSolution
{
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Verify that the warning is cleared upon closing solution)

    Build-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 1 $warnings.Count

    $warning = $warnings[$warnings.Count - 1]

    Close-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 0 $warnings.Count
}


function ProjectRetargeting-ClearWarningUponPackageReinstallationAndBuild
{
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Verify that the warning is cleared after reinstalling the package and building the solution)

    Build-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 1 $warnings.Count

    $warning = $warnings[$warnings.Count - 1]

    Update-Package -Reinstall -Project $projectName -Source $context.RepositoryPath
    Build-Solution

    $errorlist = Get-Errors

    Assert-AreEqual 0 $errorlist.Count

    $warnings = Get-Warnings

    Assert-AreEqual 0 $warnings.Count
}

function ProjectRetargeting-ClearReinstallationFlagRetargetBackToOriginalFramework {
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Assert that the package reference has requireReinstallation flag marked to true)

    $p = Get-Project $projectName
    $packageReferences = Get-ProjectPackageReferences $p

    Assert-AreEqual 1 $packageReferences.Count
    Assert-True $packageReferences[0].RequireReinstallation

    # Change the framework of the project back to .NET 4.0 and verify that the reinstallation is cleared

    $p = Get-Project $projectName
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=4.0'

    $p = Get-Project $projectName
    $packageReferences = Get-ProjectPackageReferences $p

    Assert-AreEqual 1 $packageReferences.Count
    Assert-False $packageReferences[0].RequireReinstallation
}

function ProjectRetargeting-ClearReinstallationFlagUponPackageReinstallation {
    param($context)

    # Arrange
    $p = New-ClassLibrary

    $p | Install-Package PackageTargetingNet40AndNet40Client -Source $context.RepositoryPath

    Assert-Package $p 'PackageTargetingNet40AndNet40Client'

    # Act (change the target framework of the project to 4.0-Client and verify that an error is thrown )

    $projectName = $p.Name
    $p.Properties.Item("TargetFrameworkMoniker").Value = '.NETFramework,Version=v4.0,Profile=Client'

    # Assert (Assert that the package reference has requireReinstallation flag marked to true)

    $p = Get-Project $projectName
    $packageReferences = Get-ProjectPackageReferences $p

    Assert-AreEqual 1 $packageReferences.Count
    Assert-True $packageReferences[0].RequireReinstallation

    # Assert (Assert that the package reinstallation flag is removed when the package is updated)
    Update-Package -Reinstall -Project $projectName -Source $context.RepositoryPath

    $p = Get-Project $projectName
    $packageReferences = Get-ProjectPackageReferences $p

    Assert-AreEqual 1 $packageReferences.Count
    Assert-False $packageReferences[0].RequireReinstallation
}