<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->


<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="_CheckRequiredProperties" DefaultTargets="Build">
  <PropertyGroup>
    <WixTargetsImported>true</WixTargetsImported>
  </PropertyGroup>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  Extension Points
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!-- Allow a user-customized targets files to be used as part of the build. -->
  <Import Project="$(CustomBeforeWixTargets)" Condition=" '$(CustomBeforeWixTargets)' != '' and Exists('$(CustomBeforeWixTargets)')" />

  <!-- These properties can be overridden to support non-default installations. -->
  <PropertyGroup>
    <WixBinDir Condition=" '$(WixBinDir)' == ''">$(MSBuildThisFileDirectory)</WixBinDir>
    <WixTasksPath Condition=" '$(WixTasksPath)' == '' ">$(WixBinDir)WixTasks.dll</WixTasksPath>
    <WixHarvestTargetsPath Condition=" '$(WixHarvestTargetsPath)' == '' ">$(WixBinDir)wix.harvest.targets</WixHarvestTargetsPath>
    <WixSigningTargetsPath Condition=" '$(WixSigningTargetsPath)' == '' ">$(WixBinDir)wix.signing.targets</WixSigningTargetsPath>
    <LuxTargetsPath Condition=" '$(LuxTargetsPath)' == '' ">$(WixBinDir)lux.targets</LuxTargetsPath>
    <LuxTasksPath Condition=" '$(LuxTasksPath)' == '' ">$(WixBinDir)LuxTasks.dll</LuxTasksPath>
  </PropertyGroup>

  <!-- This makes the project files a dependency of all targets so that things rebuild if they change -->
  <PropertyGroup> 
    <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
    <MSBuildAllProjects Condition="Exists('$(WixHarvestTargetsPath)')">$(MSBuildAllProjects);$(WixHarvestTargetsPath)</MSBuildAllProjects>
    <MSBuildAllProjects Condition="Exists('$(WixSigningTargetsPath)')">$(MSBuildAllProjects);$(WixSigningTargetsPath)</MSBuildAllProjects>
    <MSBuildAllProjects Condition="Exists('$(LuxTargetsPath)')">$(MSBuildAllProjects);$(LuxTargetsPath)</MSBuildAllProjects>
    <MSBuildAllProjects Condition="Exists('$(CustomBeforeWixTargets)')">$(MSBuildAllProjects);$(CustomBeforeWixTargets)</MSBuildAllProjects>
    <MSBuildAllProjects Condition="Exists('$(CustomAfterWixTargets)')">$(MSBuildAllProjects);$(CustomAfterWixTargets)</MSBuildAllProjects>
  </PropertyGroup>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  Declarations for Microsoft.Common.targets
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <PropertyGroup>
    <DefaultLanguageSourceExtension>.wxs</DefaultLanguageSourceExtension>
    <Language>wix</Language>
    <TargetRuntime>Managed</TargetRuntime>

    <!-- Use OutputName to set the AssemblyName for Microsoft.Common.targets -->
    <OutputName Condition=" '$(OutputName)'=='' ">$(MSBuildProjectName)</OutputName>
    <AssemblyName>$(OutputName)</AssemblyName>

    <!-- Default the OutputType to a known WiX toolset TYPE.  -->
    <_OriginalOutputType>$(OutputType)</_OriginalOutputType>
    <OutputType Condition=" '$(OutputType)' == '' ">Package</OutputType>
  </PropertyGroup>

  <!--
  IDE Macros available from both integrated builds and from command line builds.
  The following properties are 'macros' that are available via IDE for pre and post build steps.
  All of them should be added to WixBuildMacroCollection to ensure that they are shown in the UI.
  -->
  <PropertyGroup>
    <TargetExt Condition=" '$(OutputType)' == 'Package' ">.msi</TargetExt>
    <TargetExt Condition=" '$(OutputType)' == 'Module' ">.msm</TargetExt>
    <TargetExt Condition=" '$(OutputType)' == 'PatchCreation' ">.pcp</TargetExt>
    <TargetExt Condition=" '$(OutputType)' == 'Library' ">.wixlib</TargetExt>
    <TargetExt Condition=" '$(OutputType)' == 'Bundle' ">.exe</TargetExt>
  </PropertyGroup>

  <!-- Provide the correct output name for the .wixpdb -->
  <ItemGroup Condition="'$(_DebugSymbolsProduced)' == 'true'">
    <_DebugSymbolsIntermediatePath Include="$(PdbOutputDir)$(TargetPdbName)" Condition=" '@(_DebugSymbolsIntermediatePath)' == '' " />
  </ItemGroup>

  <Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />

  <PropertyGroup>
    <!-- Default pdb output path to the intermediate output directory -->
    <PdbOutputDir Condition=" '$(PdbOutputDir)'=='' ">$(IntermediateOutputPath)</PdbOutputDir>
    <PdbOutputDir Condition=" '$(PdbOutputDir)' != '' and !HasTrailingSlash('$(PdbOutputDir)') ">$(PdbOutputDir)\</PdbOutputDir>

    <!-- Example, C:\MyProjects\MyProject\bin\debug\ -->
    <TargetPdbDir Condition=" '$(PdbOutputDir)'!='' ">$([System.IO.Path]::GetFullPath(`$([System.IO.Path]::Combine(`$(MSBuildProjectDirectory)`, `$(PdbOutputDir)`))`))</TargetPdbDir>

    <!-- Example, MySetup.wixpdb" -->
    <TargetPdbName Condition=" '$(TargetPdbName)' == '' ">$(TargetName).wixpdb</TargetPdbName>

    <!-- Example, C:\MyProjects\MyProject\bin\debug\MyPackage.wixpdb -->
    <TargetPdbPath Condition=" '$(TargetPdbPath)' == '' ">$(TargetPdbDir)$(TargetPdbName)</TargetPdbPath>
  </PropertyGroup>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  Property Declarations
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!-- These tasks can be used as general-purpose build tasks. -->
  <UsingTask TaskName="Candle" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="Lit" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="Light" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="Torch" AssemblyFile="$(WixTasksPath)" />

  <!-- These tasks are specific to the build process defined in this file, and are not considered general-purpose build tasks. -->
  <UsingTask TaskName="CreateItemAvoidingInference" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="CreateProjectReferenceDefineConstants" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="WixAssignCulture" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="ResolveWixReferences" AssemblyFile="$(WixTasksPath)"/>
  <UsingTask TaskName="ReplaceString" AssemblyFile="$(WixTasksPath)"/>
  <UsingTask TaskName="GetCabList" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="GetLooseFileList" AssemblyFile="$(WixTasksPath)" />
  <UsingTask TaskName="GenerateCompileWithObjectPath" AssemblyFile="$(WixTasksPath)"/>

  <!-- WiX tools are 32bit EXEs, so run them out-of-proc when MSBuild is not 32bit. -->
  <PropertyGroup>
    <RunWixToolsOutOfProc Condition=" '$(PROCESSOR_ARCHITECTURE)'!='x86' ">true</RunWixToolsOutOfProc>
  </PropertyGroup>

  <PropertyGroup>
    <BindContentsFile Condition=" '$(BindContentsFile)' == '' ">$(MSBuildProjectFile).BindContentsFileList.txt</BindContentsFile>
    <BindOutputsFile Condition=" '$(BindOutputsFile)' == '' ">$(MSBuildProjectFile).BindOutputsFileList.txt</BindOutputsFile>
    <BindBuiltOutputsFile Condition=" '$(BindBuiltOutputsFile)' == '' ">$(MSBuildProjectFile).BindBuiltOutputsFileList.txt</BindBuiltOutputsFile>
  </PropertyGroup>

  <PropertyGroup>
    <CabinetCachePath Condition=" '$(CabinetCachePath)'=='' and '$(ReuseCabinetCache)'=='true' ">$(IntermediateOutputPath)cabcache\</CabinetCachePath>
  </PropertyGroup>

  <PropertyGroup>
    <WixToolDir Condition=" '$(WixToolDir)' == ''">$(WixBinDir)</WixToolDir>
    <WixExtDir Condition=" '$(WixExtDir)' == ''">$(WixToolDir)</WixExtDir>
  </PropertyGroup>

  <!--
  Set the SignTargetPath item directly when output is a Bundle. The AssignCultures target
  sets SignTargetPath item for other output types based on the cultures provided.
  -->
  <ItemGroup>
    <SignTargetPath Include="$(TargetPath)" Condition=" '$(OutputType)' == 'Bundle' AND '$(SignOutput)' == 'true' AND '$(SuppressLayout)' != 'true' " />
  </ItemGroup>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  Default Compiler, Linker, and Librarian Property Declarations
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!-- If WixExtension was passed in via the command line, then convert it to an ItemGroup -->
  <ItemGroup>
    <WixExtension Include="$(WixExtension)"  Condition=" '$(WixExtension)' != '' " />
  </ItemGroup>

  <!-- Defaut Compiler properties. -->
  <PropertyGroup>
    <CompilerNoLogo Condition=" '$(CompilerNoLogo)' == '' ">$(NoLogo)</CompilerNoLogo>
    <CompilerSuppressAllWarnings Condition=" '$(CompilerSuppressAllWarnings)' == '' ">$(SuppressAllWarnings)</CompilerSuppressAllWarnings>
    <CompilerSuppressSpecificWarnings Condition=" '$(CompilerSuppressSpecificWarnings)' == '' ">$(SuppressSpecificWarnings)</CompilerSuppressSpecificWarnings>
    <CompilerTreatWarningsAsErrors Condition=" '$(CompilerTreatWarningsAsErrors)' == '' ">$(TreatWarningsAsErrors)</CompilerTreatWarningsAsErrors>
    <CompilerTreatSpecificWarningsAsErrors Condition=" '$(CompilerTreatSpecificWarningsAsErrors)' == '' ">$(TreatSpecificWarningsAsErrors)</CompilerTreatSpecificWarningsAsErrors>
    <CompilerVerboseOutput Condition=" '$(CompilerVerboseOutput)' == '' ">$(VerboseOutput)</CompilerVerboseOutput>
<!-- TODO: This probably doesn't work any longer since Platform won't be defined until Microsoft.Common.targets is included -->
    <InstallerPlatform Condition=" '$(InstallerPlatform)' == '' and '$(Platform)' != 'AnyCPU' and '$(Platform)' != 'Any CPU' ">$(Platform)</InstallerPlatform>
  </PropertyGroup>

  <!-- Default Lib properties. -->
  <PropertyGroup>
    <LibNoLogo Condition=" '$(LibNoLogo)' == '' ">$(NoLogo)</LibNoLogo>
    <LibBindFiles Condition=" '$(LibBindFiles)' == '' ">$(BindFiles)</LibBindFiles>
    <LibPedantic Condition=" '$(LibPedantic)' == '' ">$(Pedantic)</LibPedantic>
    <LibSuppressAllWarnings Condition=" '$(LibSuppressAllWarnings)' == '' ">$(SuppressAllWarnings)</LibSuppressAllWarnings>
    <LibSuppressSpecificWarnings Condition=" '$(LibSuppressSpecificWarnings)' == '' ">$(SuppressSpecificWarnings)</LibSuppressSpecificWarnings>
    <LibSuppressSchemaValidation Condition=" '$(LibSuppressSchemaValidation)' == '' ">$(SuppressSchemaValidation)</LibSuppressSchemaValidation>
    <LibSuppressIntermediateFileVersionMatching Condition=" '$(LibSuppressIntermediateFileVersionMatching)' == '' ">$(SuppressIntermediateFileVersionMatching)</LibSuppressIntermediateFileVersionMatching>
    <LibTreatWarningsAsErrors Condition=" '$(LibTreatWarningsAsErrors)' == '' ">$(TreatWarningsAsErrors)</LibTreatWarningsAsErrors>
    <LibTreatSpecificWarningsAsErrors Condition=" '$(LibTreatSpecificWarningsAsErrors)' == '' ">$(TreatSpecificWarningsAsErrors)</LibTreatSpecificWarningsAsErrors>
    <LibVerboseOutput Condition=" '$(LibVerboseOutput)' == '' ">$(VerboseOutput)</LibVerboseOutput>
  </PropertyGroup>

  <!-- Default Linker properties. -->
  <PropertyGroup>
    <LinkerNoLogo Condition=" '$(LinkerNoLogo)' == '' ">$(NoLogo)</LinkerNoLogo>
    <LinkerBindFiles Condition=" '$(LinkerBindFiles)' == '' ">$(BindFiles)</LinkerBindFiles>
    <LinkerPedantic Condition=" '$(LinkerPedantic)' == '' ">$(Pedantic)</LinkerPedantic>
    <LinkerSuppressAllWarnings Condition=" '$(LinkerSuppressAllWarnings)' == '' ">$(SuppressAllWarnings)</LinkerSuppressAllWarnings>
    <LinkerSuppressSpecificWarnings Condition=" '$(LinkerSuppressSpecificWarnings)' == '' ">$(SuppressSpecificWarnings)</LinkerSuppressSpecificWarnings>
    <LinkerSuppressSchemaValidation Condition=" '$(LinkerSuppressSchemaValidation)' == '' ">$(SuppressSchemaValidation)</LinkerSuppressSchemaValidation>
    <LinkerSuppressIntermediateFileVersionMatching Condition=" '$(LinkerSuppressIntermediateFileVersionMatching)' == '' ">$(SuppressIntermediateFileVersionMatching)</LinkerSuppressIntermediateFileVersionMatching>
    <LinkerTreatWarningsAsErrors Condition=" '$(LinkerTreatWarningsAsErrors)' == '' ">$(TreatWarningsAsErrors)</LinkerTreatWarningsAsErrors>
    <LinkerTreatSpecificWarningsAsErrors Condition=" '$(LinkerTreatSpecificWarningsAsErrors)' == '' ">$(TreatSpecificWarningsAsErrors)</LinkerTreatSpecificWarningsAsErrors>
    <LinkerVerboseOutput Condition=" '$(LinkerVerboseOutput)' == '' ">$(VerboseOutput)</LinkerVerboseOutput>
  </PropertyGroup>

  <!-- If BindInputPaths (or LinkerBindInputPaths) was passed in via the command line, then convert it to an ItemGroup -->
  <ItemGroup>
    <BindInputPaths Include="$(BindInputPaths)"  Condition=" '$(BindInputPaths)' != '' " />
    <LinkerBindInputPaths Include="$(LinkerBindInputPaths)"  Condition=" '$(LinkerBindInputPaths)' != '' " />
  </ItemGroup>

  <!-- Default Lit and Light "properties" -->
  <ItemGroup>
    <LinkerBindInputPaths Condition=" '@(LinkerBindInputPaths)' == '' " Include="@(BindInputPaths)" />
  </ItemGroup>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  Initial Targets
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!--
  ==================================================================================================
  _CheckRequiredProperties

    Checks properties that must be set in the main project file or on the command line before
    using this .TARGETS file.

    [IN]
    $(OutputName) - The name of the MSI/MSM/wixlib to build (without the extension)
    $(OutputType) - Possible values are 'package', 'PatchCreation', 'module', 'library', 'bundle'
  ==================================================================================================
  -->
  <PropertyGroup>
    <_PleaseSetThisInProjectFile>Please set this in the project file before the &lt;Import&gt; of the wix.targets file.</_PleaseSetThisInProjectFile>
    <_OutputTypeDescription>The OutputType defines whether a Windows Installer package (.msi), PatchCreation (.pcp), merge module (.msm), wix library (.wixlib), or self-extracting executable (.exe) is being built. $(_PleaseSetThisInProjectFile) Possible values are 'Package', 'Module', 'Library', and 'Bundle'.</_OutputTypeDescription>
  </PropertyGroup>
  <Target Name="_CheckRequiredProperties">

    <Error
      Code="WIXTARGETS100"
      Condition=" '$(OutputName)' == '' "
      Text="The OutputName property is not set in project &quot;$(MSBuildProjectFile)&quot;. The OutputName defines the name of the output without a file extension. $(_PleaseSetThisInProjectFile)" />

    <Warning
      Code="WIXTARGETS101"
      Condition=" '$(_OriginalOutputType)' == '' "
      Text="The OutputType property is not set in project &quot;$(MSBuildProjectFile)&quot;. Defaulting to '$(OutputType)'. $(_OutputTypeDescription)" />

    <Error
      Code="WIXTARGETS102"
      Condition=" '$(OutputType)' != 'Package' and '$(OutputType)' != 'PatchCreation' and '$(OutputType)' != 'Module' and '$(OutputType)' != 'Library' and '$(OutputType)' != 'Bundle' "
      Text="The OutputType property '$(OutputType)' is not valid in project &quot;$(MSBuildProjectFile)&quot;. $(_OutputTypeDescription)" />

    <Error
      Code="WIXTARGETS103"
      Condition=" '$(MSBuildToolsVersion)' == '' OR '$(MSBuildToolsVersion)' &lt; '4.0' "
      Text="MSBuild v$(MSBuildToolsVersion) is not supported by the project &quot;$(MSBuildProjectFile)&quot;. You must use MSBuild v4.0 or later." />

  </Target>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  Build Targets
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!--
  ==================================================================================================
  CoreBuild - OVERRIDE DependsOn

    The core build step calls each of the build targets.

    This is where we insert our targets into the build process.
  ==================================================================================================
  -->
  <PropertyGroup>
    <CoreBuildDependsOn>
      BuildOnlySettings;
      PrepareForBuild;
      PreBuildEvent;
      ResolveReferences;

      CompileAndLink;
      Signing;

      GetTargetPath;
      PrepareForRun;
      IncrementalClean;
      PostBuildEvent
    </CoreBuildDependsOn>
  </PropertyGroup>


    <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  Resolve References Targets
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!--
  ==================================================================================================
  ResolveReferences - OVERRIDE DependsOn

  ==================================================================================================
  -->
  <PropertyGroup>
    <ResolveReferencesDependsOn>
      BeforeResolveReferences;
      AssignProjectConfiguration;
      ResolveProjectReferences;
      ResolveWixLibraryReferences;
      ResolveWixExtensionReferences;
      AfterResolveReferences
    </ResolveReferencesDependsOn>
  </PropertyGroup>

  <!--
  ================================================================================================
  ResolveProjectReferences

    Builds all of the referenced projects to get their outputs.

    [IN]
    @(NonVCProjectReference) - The list of non-VC project references.

    [OUT]
    @(ProjectReferenceWithConfiguration) - The list of non-VC project references.
    @(WixLibProjects) - Paths to any .wixlibs that were built by referenced projects.
  ================================================================================================
  -->
  <Target
    Name="ResolveProjectReferences"
    DependsOnTargets="AssignProjectConfiguration;_SplitProjectReferencesByFileExistence"
    Condition=" '@(ProjectReferenceWithConfiguration)' != '' ">

    <!-- Issue a warning for each non-existent project. -->
    <Warning
      Text="The referenced project '%(_MSBuildProjectReferenceNonexistent.Identity)' does not exist."
      Condition=" '@(_MSBuildProjectReferenceNonexistent)' != '' " />

    <!--
    When building this project from the IDE or when building a .sln from the command line or
    when only building .wixlib project references, gather the referenced build outputs. The
    code that builds the .sln will already have built the project, so there's no need to do
    it again here and when building only .wixlib project references we'll use the results to
    determine which projects to build.

    The ContinueOnError setting is here so that, during project load, as much information as
    possible will be passed to the compilers.
    -->
    <MSBuild
      Projects="@(_MSBuildProjectReferenceExistent)"
      Targets="%(_MSBuildProjectReferenceExistent.Targets);GetTargetPath"
      Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration);%(_MSBuildProjectReferenceExistent.SetPlatform)"
      Condition="('$(BuildingSolutionFile)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true' or '$(BuildProjectReferences)' != 'true') and '@(_MSBuildProjectReferenceExistent)' != '' "
      ContinueOnError="!$(BuildingProject)">

      <Output TaskParameter="TargetOutputs" ItemName="_GatheredProjectReferencePaths" />
    </MSBuild>

    <!--
    Determine which project references should be built. Note: we will not build any project references
    if building in the IDE because it builds project references directly.

    If BuildProjectReferences is 'true' (the default) then take all MSBuild project references that exist
    on disk and add them to the list of things to build. This is the easy case.
    -->
    <CreateItem
      Include="@(_MSBuildProjectReferenceExistent)"
      Condition=" '$(BuildProjectReferences)' == 'true' and '$(BuildingInsideVisualStudio)' != 'true' ">

      <Output TaskParameter="Include" ItemName="_ProjectReferencesToBuild" />
    </CreateItem>

    <!--
    If BuildProjectReferences is 'wixlib' then build only the MSBuild project references that exist and
    create a .wixlib file. That requires us to first filter the gathered project references down to only
    those that build .wixlibs.
    -->
    <CreateItem
      Include="@(_GatheredProjectReferencePaths)"
      Condition=" '$(BuildProjectReferences)' == 'wixlib' and '%(Extension)' == '.wixlib' and '$(BuildingInsideVisualStudio)' != 'true' ">

      <Output TaskParameter="Include" ItemName="_ReferencedWixLibPaths" />
    </CreateItem>

    <!--
    The second step when building only 'wixlib' project references is to create the list of existing MSBuild
    project references that do *not* build a .wixlib. These are the projects that will be skipped.
     -->
    <CreateItem
      Include="@(_MSBuildProjectReferenceExistent->'%(FullPath)')"
      Exclude="@(_ReferencedWixLibPaths->'%(MSBuildSourceProjectFile)')"
      Condition=" '$(BuildProjectReferences)' == 'wixlib' and '$(BuildingInsideVisualStudio)' != 'true' ">

      <Output TaskParameter="Include" ItemName="_ProjectReferencesToSkip" />
    </CreateItem>

    <!--
    Finally, when building only 'wixlib' project references, the list of projects to build are naturally the
    list of projects *not* being skipped.
    -->
    <CreateItem
      Include="@(_MSBuildProjectReferenceExistent->'%(FullPath)')"
      Exclude="@(_ProjectReferencesToSkip)"
      Condition=" '$(BuildProjectReferences)' == 'wixlib' and '$(BuildingInsideVisualStudio)' != 'true' ">

      <Output TaskParameter="Include" ItemName="_ProjectReferencesToBuild" />
    </CreateItem>

    <!-- Display a warning for all projects being skipped. -->
    <Warning
      Text="BuildProjectReferences set to '$(BuildProjectReferences)'. Skipping the non-Library project: %(_ProjectReferencesToSkip.Identity)"
      Condition=" '@(_ProjectReferencesToSkip)' != '' " />

    <Message
      Importance="low"
      Text="Project reference to build: %(_ProjectReferencesToBuild.Identity), properties: %(_ProjectReferencesToBuild.Properties)"
      Condition=" '@(_ProjectReferencesToBuild)' != '' " />

    <!--
    Build referenced projects when building from the command line.

    The $(ProjectReferenceBuildTargets) will normally be blank so that the project's default target
    is used during a P2P reference. However if a custom build process requires that the referenced
    project has a different target to build it can be specified.
    -->
    <MSBuild
      Projects="@(_ProjectReferencesToBuild)"
      Targets="$(ProjectReferenceBuildTargets)"
      Properties="%(_ProjectReferencesToBuild.SetConfiguration);%(_ProjectReferencesToBuild.SetPlatform)"
      Condition=" '@(_ProjectReferencesToBuild)' != '' ">

      <Output TaskParameter="TargetOutputs" ItemName="_BuiltProjectReferencePaths" />
    </MSBuild>

    <!-- 
    VC project references must build GetNativeTargetPath because neither GetTargetPath nor the return of the default build
    target return the output for a native .vcxproj. 
    -->
    <MSBuild
      Projects="@(_MSBuildProjectReferenceExistent)"
      Targets="GetNativeTargetPath"
      Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration);%(_MSBuildProjectReferenceExistent.SetPlatform)"
      Condition=" '@(ProjectReferenceWithConfiguration)' != '' and '%(_MSBuildProjectReferenceExistent.Extension)' == '.vcxproj' ">

      <Output TaskParameter="TargetOutputs" ItemName="_ResolvedProjectReferencePaths" />
      <Output TaskParameter="TargetOutputs" ItemName="_MSBuildResolvedProjectReferencePaths" />
    </MSBuild>

    <!-- Assign the unique gathered and built project references to the resolved project
         reference paths. -->
    <RemoveDuplicates Inputs="@(_GatheredProjectReferencePaths);@(_BuiltProjectReferencePaths)">
      <Output TaskParameter="Filtered" ItemName="_ResolvedProjectReferencePaths" />
      <Output TaskParameter="Filtered" ItemName="_MSBuildResolvedProjectReferencePaths" />
    </RemoveDuplicates>

    <!-- Create list of all .wixlib project references. -->
    <CreateItem
      Include="@(_ResolvedProjectReferencePaths)"
      Condition=" '%(Extension)' == '.wixlib' ">

      <Output TaskParameter="Include" ItemName="WixLibProjects" />
    </CreateItem>

    <Message
      Importance="low"
      Text="Library from referenced projects: %(WixLibProjects.Identity)"
      Condition=" '@(WixLibProjects)' != '' " />

  </Target>

  <!--
  ================================================================================================
  ResolveWixLibraryReferences

    Resolve the library references to full paths.

    [IN]
    @(WixLibrary) - The list of .wixlib files.
    
    [OUT]
    @(_ResolvedWixLibraryPaths) - Item group with full paths to libraries
  ================================================================================================
  -->
  <PropertyGroup>
    <ResolveWixLibraryReferencesDependsOn></ResolveWixLibraryReferencesDependsOn>
  </PropertyGroup>
  <Target
    Name="ResolveWixLibraryReferences"
    DependsOnTargets="$(ResolveWixLibraryReferencesDependsOn)"
    Condition=" '@(WixLibrary)' != ''">

    <!--
    The WixLibrarySearchPaths property is set to find assemblies in the following order:

        (1) $(ReferencePaths) - the reference paths property, which comes from the .USER file.
        (2) The hintpath from the referenced item itself, indicated by {HintPathFromItem}.
        (3) Treat the reference's Include as if it were a real file name.
        (4) Path specified by the WixExtDir property.
    -->
    <CreateProperty Condition=" '$(WixLibrarySearchPaths)' == '' " Value="
      $(ReferencePaths);
      {HintPathFromItem};
      {RawFileName};
      $(WixExtDir)
      ">
      <Output TaskParameter="Value" PropertyName="WixLibrarySearchPaths" />
    </CreateProperty>

    <ResolveWixReferences
      WixReferences="@(WixLibrary)"
      SearchPaths="$(WixLibrarySearchPaths)"
      SearchFilenameExtensions=".wixlib">
      <Output TaskParameter="ResolvedWixReferences" ItemName="_AllResolvedWixLibraryPaths" />
    </ResolveWixReferences>

    <!-- Remove duplicate library items that would cause build errors -->
    <RemoveDuplicates Inputs="@(_AllResolvedWixLibraryPaths)">
      <Output TaskParameter="Filtered" ItemName="_ResolvedWixLibraryPaths" />
    </RemoveDuplicates>

  </Target>

  <!--
  ==================================================================================================
  ResolveWixExtensionReferences

    Resolves WiX extension references to full paths. Any properties you use
    to resolve paths to extensions must be defined before importing this
    file or the extensions will be automatically resolved to $(WixExtDir).

    [IN]
    @(WixExtension) - WixExtension item group

    [OUT]
    @(_ResolvedWixExtensionPaths) - Item group with full paths to extensions
  ==================================================================================================
  -->
  <PropertyGroup>
    <ResolveWixExtensionReferencesDependsOn></ResolveWixExtensionReferencesDependsOn>
  </PropertyGroup>
  <Target
    Name="ResolveWixExtensionReferences"
    DependsOnTargets="$(ResolveWixExtensionReferencesDependsOn)"
    Condition=" '@(WixExtension)' != ''">

    <!--
    The WixExtensionSearchPaths property is set to find assemblies in the following order:

        (1) $(ReferencePaths) - the reference paths property, which comes from the .USER file.
        (2) The hintpath from the referenced item itself, indicated by {HintPathFromItem}.
        (3) Treat the reference's Include as if it were a real file name.
        (4) Path specified by the WixExtDir property.
    -->
    <CreateProperty Condition=" '$(WixExtensionSearchPaths)' == '' " Value="
      $(ReferencePaths);
      {HintPathFromItem};
      {RawFileName};
      $(WixExtDir)
      ">
      <Output TaskParameter="Value" PropertyName="WixExtensionSearchPaths" />
    </CreateProperty>

    <ResolveWixReferences
      WixReferences="@(WixExtension)"
      SearchPaths="$(WixExtensionSearchPaths)"
      SearchFilenameExtensions=".dll">
      <Output TaskParameter="ResolvedWixReferences" ItemName="_AllResolvedWixExtensionPaths" />
    </ResolveWixReferences>

    <!-- Remove duplicate extension items that would cause build errors -->
    <RemoveDuplicates Inputs="@(_AllResolvedWixExtensionPaths)">
      <Output TaskParameter="Filtered" ItemName="_ResolvedWixExtensionPaths" />
    </RemoveDuplicates>
  </Target>

  <!--
  ================================================================================================
  GetTargetPath - OVERRIDE DependsOn

    This stand-alone target returns the name of the build product (i.e. MSI, MSM) that would be
    produced if we built this project.
  ================================================================================================
  -->
  <PropertyGroup>
    <GetTargetPathDependsOn>AssignCultures</GetTargetPathDependsOn>
  </PropertyGroup>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  CompileAndLink Targets
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!--
  ==================================================================================================
  CompileAndLink
  ==================================================================================================
  -->
  <PropertyGroup>
    <CompileAndLinkDependsOn>
      ResolveReferences;
      BeforeCompile;
      _TimeStampBeforeCompile;
      Harvest;
      Compile;
      Lib;
      Link;
      UpdateLinkFileWrites;
      _TimeStampAfterCompile;
      AfterCompile
    </CompileAndLinkDependsOn>
  </PropertyGroup>
  <Target
    Name="CompileAndLink"
    DependsOnTargets="$(CompileAndLinkDependsOn)" />

  <!--
  ==================================================================================================
  CalculateDefineConstants

    Adds project references to the constants passed into the compiler.

    [IN]
    @(_ResolvedProjectReferencePaths) - paths to projects' outputs
    $(VSProjectConfigurations) - map of project names to configurations, provided by VS when building in the IDE

    [OUT]
    $(ProjectReferenceDefineConstants) - the list of referenced project variables to be passed into the compiler
  ==================================================================================================
  -->
  <PropertyGroup>
    <CalculateDefineConstantsDependsOn>ResolveReferences</CalculateDefineConstantsDependsOn>
  </PropertyGroup>
  <Target
      Name="CalculateDefineConstants"
      DependsOnTargets="$(CalculateDefineConstantsDependsOn)"
      Condition=" '@(_ResolvedProjectReferencePaths)' != '' ">

    <PropertyGroup>
      <ProjectDefineConstants>
        Configuration=$(ConfigurationName);
        OutDir=$(OutDir);
        Platform=$(PlatformName);
        ProjectDir=$(ProjectDir);
        ProjectExt=$(ProjectExt);
        ProjectFileName=$(ProjectFileName);
        ProjectName=$(ProjectName);
        ProjectPath=$(ProjectPath);
        TargetDir=$(TargetDir);
        TargetExt=$(TargetExt);
        TargetFileName=$(TargetFileName);
        TargetName=$(TargetName);
        TargetPath=$(TargetPath);
      </ProjectDefineConstants>
    </PropertyGroup>

    <PropertyGroup>
      <SolutionDefineConstants Condition=" '$(DevEnvDir)'!='*Undefined*' ">$(SolutionDefineConstants);DevEnvDir=$(DevEnvDir)</SolutionDefineConstants>
      <SolutionDefineConstants Condition=" '$(SolutionDir)'!='*Undefined*' ">$(SolutionDefineConstants);SolutionDir=$(SolutionDir)</SolutionDefineConstants>
      <SolutionDefineConstants Condition=" '$(SolutionExt)'!='*Undefined*' ">$(SolutionDefineConstants);SolutionExt=$(SolutionExt)</SolutionDefineConstants>
      <SolutionDefineConstants Condition=" '$(SolutionFileName)'!='*Undefined*' ">$(SolutionDefineConstants);SolutionFileName=$(SolutionFileName)</SolutionDefineConstants>
      <SolutionDefineConstants Condition=" '$(SolutionName)'!='*Undefined*' ">$(SolutionDefineConstants);SolutionName=$(SolutionName)</SolutionDefineConstants>
      <SolutionDefineConstants Condition=" '$(SolutionPath)'!='*Undefined*' ">$(SolutionDefineConstants);SolutionPath=$(SolutionPath)</SolutionDefineConstants>
    </PropertyGroup>

    <CreateProjectReferenceDefineConstants
        ProjectReferencePaths="@(_ResolvedProjectReferencePaths)"
        ProjectConfigurations="$(VSProjectConfigurations)">

      <Output TaskParameter="DefineConstants" PropertyName="ProjectReferenceDefineConstants" />
    </CreateProjectReferenceDefineConstants>
  </Target>

  <!--
  ================================================================================================
  GenerateCompileWithObjectPath

    Generates metadata on the for compile output objects.

  ================================================================================================
  -->
  <PropertyGroup>
    <GenerateCompileWithObjectPathDependsOn></GenerateCompileWithObjectPathDependsOn>
  </PropertyGroup>
  <Target
      Name="GenerateCompileWithObjectPath"
      Condition=" '@(Compile)' != '' ">

    <GenerateCompileWithObjectPath
        Compile="@(Compile)"
        IntermediateOutputPath="$(IntermediateOutputPath)">
      <Output TaskParameter="CompileWithObjectPath" ItemName="_CompileWithObjectPath" />
    </GenerateCompileWithObjectPath>

  </Target>

  <!--
  ================================================================================================
  Compile

    Compiles the wxs files into wixobj files using candle.exe.

    [IN]
    @(Compile) - The list of wxs files to compile.
    @(Content) - Files that the project uses in the installer.
    @(WixExtension) - The list of wixlib or wix dll extensions.

    [OUT]
    @(CompileObjOutput) - The compiled .wixobj files.
  ================================================================================================
  -->
  <PropertyGroup>
    <CompileDependsOn>
      PrepareForBuild;
      ResolveReferences;
      CalculateDefineConstants;
      GenerateCompileWithObjectPath
    </CompileDependsOn>
  </PropertyGroup>
  <Target
      Name="Compile"
      Inputs="@(Compile);
              @(Content);
              @(_ResolvedWixExtensionPaths);
              @(_ResolvedProjectReferencePaths);
              $(MSBuildAllProjects)"
      Outputs="@(_CompileWithObjectPath -> '%(ObjectPath)%(Filename).wixobj')"
      DependsOnTargets="$(CompileDependsOn)"
      Condition=" '@(Compile)' != '' ">

    <Candle
        SourceFiles="@(_CompileWithObjectPath)"
        AdditionalOptions="$(CompilerAdditionalOptions)" 
        DefineConstants="$(DefineConstants);$(SolutionDefineConstants);$(ProjectDefineConstants);$(ProjectReferenceDefineConstants)"
        ExtensionDirectory="$(WixExtDir)"
        Extensions="@(_ResolvedWixExtensionPaths)"
        PreprocessToStdOut="$(PreprocessToStdOut)"
        PreprocessToFile="$(PreprocessToFile)"
        IncludeSearchPaths="$(IncludeSearchPaths)"
        InstallerPlatform="$(InstallerPlatform)"
        NoLogo="$(CompilerNoLogo)"
        OutputFile="%(_CompileWithObjectPath.ObjectPath)"
        Pedantic="$(Pedantic)"
        ReferencePaths="$(ReferencePaths)"
        RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
        SuppressAllWarnings="$(CompilerSuppressAllWarnings)"
        SuppressSpecificWarnings="$(CompilerSuppressSpecificWarnings)"
        ToolPath="$(WixToolDir)"
        TreatWarningsAsErrors="$(CompilerTreatWarningsAsErrors)"
        TreatSpecificWarningsAsErrors="$(CompilerTreatSpecificWarningsAsErrors)" 
        VerboseOutput="$(CompilerVerboseOutput)">
    </Candle>

    <!-- These will be still be set even if the Compile target is up to date. -->
    <ItemGroup>
      <CompileObjOutput Include="@(_CompileWithObjectPath -> '%(ObjectPath)%(Filename).wixobj')" />
      <FileWrites Include="@(CompileObjOutput)" />
    </ItemGroup>
  </Target>

  <!--
  ================================================================================================
  Lib

    Links the .wixobj, .wxl, .wixlib, wix extensions into a .wixlib file using lit.exe.

    [IN]
    @(CompileObjOutput) - The compiled .wixobj file.
    @(EmbeddedResource) - The list of wxl files to use for localization.
    @(WixObject) - The list of .wixobj files.
    @(WixLibrary) - The list of .wixlib files.
    @(WixExtension) - The list of wix dll extension files.

    [OUT]
    $(TargetPath) - The compiled .wixlib file.
  ================================================================================================
  -->
  <PropertyGroup>
    <LibDependsOn>
      PrepareForBuild;
      ResolveReferences
    </LibDependsOn>
  </PropertyGroup>
  <Target
      Name="Lib"
      Inputs="@(CompileObjOutput);
              @(EmbeddedResource);
              @(WixObject);
              @(WixLibrary);
              @(_ResolvedWixExtensionPaths);
              $(MSBuildAllProjects)"
      Outputs="$(TargetPath)"
      DependsOnTargets="$(LibDependsOn)"
      Condition=" '$(OutputType)' == 'Library' ">

    <Lit
      ObjectFiles="@(CompileObjOutput);@(WixObject);@(WixLibProjects);@(WixLibrary)"
      AdditionalOptions="$(LibAdditionalOptions)"
      BindInputPaths="@(LinkerBindInputPaths)"
      BindFiles="$(LibBindFiles)"
      ExtensionDirectory="$(WixExtDir)"
      Extensions="@(_ResolvedWixExtensionPaths)"
      LocalizationFiles="@(EmbeddedResource)"
      NoLogo="$(LibNoLogo)"
      OutputFile="$(TargetPath)"
      Pedantic="$(LibPedantic)"
      ReferencePaths="$(ReferencePaths)"
      RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
      SuppressAllWarnings="$(LibSuppressAllWarnings)"
      SuppressIntermediateFileVersionMatching="$(LibSuppressIntermediateFileVersionMatching)"
      SuppressSchemaValidation="$(LibSuppressSchemaValidation)"
      SuppressSpecificWarnings="$(LibSuppressSpecificWarnings)"
      ToolPath="$(WixToolDir)"
      TreatWarningsAsErrors="$(LibTreatWarningsAsErrors)"
      VerboseOutput="$(LibVerboseOutput)" />
  </Target>

  <!--
  ================================================================================================
  AssignCultures

    Determines the final list of culture groups to build based on either the Cultures property or
    those specified in .wxl files. 

      Culture groups specified in the Cultures property must be specified as a semi-colon 
      delimited  list of groups, with comma-delimited cultures within a group.  
      For example:
        <Cultures>en-US,en;en-GB,en</Cultures>
      This will build 2 targets, outputing to en-US and en-GB sub-folders.  Light will first look
      for strings in the first culture (en-US or en-GB) then the second (en).

      Cultures of .wxl files will be used when the Culture property is not set.  The culture of a 
      .wxl file is determined by the Culture attribute in the WixLocalization element in the file

    Sets the OutputFolder metadata on each culture group.  In most cases this is the same as the 
    first culture in the culture group.  When the Culture's property is unspecified and no .wxl 
    files are provided this is the same as the output directory.  When the Culture's property 
    specifies a single culture group and no .wxl files are provided this is the same as the output
    directory.

    Updates the TargetPath and TargetPdbPath properties to be used in subsequent targets.

    [IN]
    @(EmbeddedResource) - The list of wxl files to use for localization.
    $(Cultures) - The list of culture groups to build.

    [OUT]
    @(CultureGroup) - The list of culture group strings with OutputFolder metadata
    $(TargetPath) - Property list of target link output MSIs/MSMs
    $(TargetPdbPath) - Property list of target output pdbs
    @(SignTargetPath) - The list of target to be signed

  ================================================================================================
  -->
  <Target
      Name="AssignCultures"
      Condition=" '$(OutputType)' == 'Package' or '$(OutputType)' == 'PatchCreation' or '$(OutputType)' == 'Module' ">

    <WixAssignCulture
        Cultures="$(Cultures)"
        Files="@(EmbeddedResource)">

      <Output TaskParameter="CultureGroups" ItemName="CultureGroup" />
    </WixAssignCulture>

    <!-- Build an itemgroup of outputs -->
    <ItemGroup>
      <_TargetPathItems Include="$(TargetDir)%(CultureGroup.OutputFolder)$(TargetName)$(TargetExt)" />
      <_TargetPdbPathItems Include="$(TargetPdbDir)%(CultureGroup.OutputFolder)$(TargetPdbName)" />
    </ItemGroup>

    <!-- Convert the itemgroup to a semicolon-delimited property -->
    <PropertyGroup>
      <TargetPath>@(_TargetPathItems)</TargetPath>
      <TargetPdbPath>@(_TargetPdbPathItems)</TargetPdbPath>
    </PropertyGroup>

    <!-- Set the sign target items, if we're signing output. -->
    <ItemGroup Condition=" '$(SignOutput)' == 'true' AND '$(SuppressLayout)' != 'true' ">
      <SignTargetPath Include="@(_TargetPathItems)" />
    </ItemGroup>
  </Target>

  <!--
  ================================================================================================
  ReadPreviousBindInputsAndBuiltOutputs

    Reads a previous build's Bind contents and built outputs file into @(_BindInputs) and
    @(_BindBuiltOutputs) respectively.

    Note: Only the *built* outputs are used because using files copied to output folder
          can cause perpetual incremental build.

          Imagine the case where you have: Msi.wixproj -> Lib.wixproj -> Exe.csproj. The
          Exe.csproj cannot be both an input to Lib.wixproj and an output of Msi.wixproj
          (as an uncompressed file) because the Lib.wixproj will always newer than the
          Exe.csproj.

    [IN]

    [OUT]
    @(_BindInputs) - the content files required to bind (i.e. the Binary/@SourceFile and File/@Source files).
    @(_BindBuiltOutputs) - the previously built .msi, .msm, .pcp, .exe .wixpdb, .cabs, etc.
                           Does not include content copied to output folder.
  ================================================================================================
  -->
  <Target
    Name="ReadPreviousBindInputsAndBuiltOutputs"
    Condition=" '$(OutputType)' == 'Bundle' or '$(OutputType)' == 'Package' or '$(OutputType)' == 'PatchCreation' or '$(OutputType)' == 'Module' ">

    <ReadLinesFromFile File="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindContentsFile)">
      <Output TaskParameter="Lines" ItemName="_BindInputs" />
    </ReadLinesFromFile>

    <ReadLinesFromFile File="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindBuiltOutputsFile)">
      <Output TaskParameter="Lines" ItemName="_BindBuiltOutputs" />
    </ReadLinesFromFile>

    <Message Importance="low" Text="Previous bind inputs: @(_BindInputs)" />
    <Message Importance="low" Text="Previous bind outputs: @(_BindBuiltOutputs)" />
  </Target>

  <!--
  ================================================================================================
  Link

    Links the .wixobj, .wxl, .wixlib, wix extensions into an .msi or .msm file using light.exe,
    once per culture group. All WXL files are passed into light and the culture switch determines
    which are used

    [IN]
    @(CompileObjOutput) - The compiled .wixobj file.
    @(CultureGroup) - The cultures to build
    @(EmbeddedResource) - The list of wxl files to use for localization.
    @(WixObject) - The list of .wixobj files.
    @(WixLibrary) - The list of .wixlib files.
    @(WixExtension) - The list of wix dll extension files.

    [OUT]
    $(TargetDir)\%(Culture)\$(TargetName)$(TargetExt) - The compiled .msi, .msm, or .exe files.
  ================================================================================================
  -->
  <PropertyGroup>
    <LinkDependsOn>
      PrepareForBuild;
      ResolveReferences;
      AssignCultures;
      ReadPreviousBindInputsAndBuiltOutputs;
    </LinkDependsOn>
  </PropertyGroup>
  <Target
      Name="Link"
      Inputs="@(CompileObjOutput);
              @(EmbeddedResource);
              @(WixObject);
              @(_ResolvedProjectReferencePaths);
              @(_ResolvedWixLibraryPaths);
              @(_ResolvedWixExtensionPaths);
              $(MSBuildAllProjects);
              @(_BindInputs)"
      Outputs="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindBuiltOutputsFile);@(_BindBuiltOutputs)"
      DependsOnTargets="$(LinkDependsOn)"
      Condition=" '$(OutputType)' == 'Bundle' or '$(OutputType)' == 'Package' or '$(OutputType)' == 'PatchCreation' or '$(OutputType)' == 'Module' ">

    <PropertyGroup>
      <PdbOutputFile>$(TargetPdbDir)%(CultureGroup.OutputFolder)$(TargetPdbName)</PdbOutputFile>
    </PropertyGroup>

    <!-- Call light using the culture subdirectory for output -->
    <Light
      ObjectFiles="@(CompileObjOutput);@(WixObject);@(WixLibProjects);@(_ResolvedWixLibraryPaths)"
      AdditionalOptions="$(LinkerAdditionalOptions)"
      AllowIdenticalRows="$(AllowIdenticalRows)"
      AllowUnresolvedReferences="$(AllowUnresolvedReferences)"
      AdditionalCub="$(AdditionalCub)"
      BackwardsCompatibleGuidGeneration="$(BackwardsCompatibleGuidGeneration)" 
      BindInputPaths="@(LinkerBindInputPaths)"
      BindFiles="$(LinkerBindFiles)"
      BindContentsFile="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindContentsFile)"
      BindOutputsFile="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindOutputsFile)"
      BindBuiltOutputsFile="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindBuiltOutputsFile)"
      CabinetCachePath="$(CabinetCachePath)"
      CabinetCreationThreadCount="$(CabinetCreationThreadCount)"
      Cultures="%(CultureGroup.Identity)"
      CustomBinder="$(CustomBinder)"
      DefaultCompressionLevel="$(DefaultCompressionLevel)"
      DropUnrealTables="$(DropUnrealTables)"
      ExactAssemblyVersions="$(ExactAssemblyVersions)"
      ExtensionDirectory="$(WixExtDir)"
      Extensions="@(_ResolvedWixExtensionPaths)"
      Ices="$(Ices)"
      LeaveTemporaryFiles="$(LeaveTemporaryFiles)"
      LocalizationFiles="@(EmbeddedResource)"
      NoLogo="$(LinkerNoLogo)"
      OutputAsXml="$(OutputAsXml)"
      OutputFile="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(TargetName)$(TargetExt)"
      PdbOutputFile="$(PdbOutputFile)"
      Pedantic="$(LinkerPedantic)"
      ReferencePaths="$(ReferencePaths)"
      ReuseCabinetCache="$(ReuseCabinetCache)"
      RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
      SuppressAclReset="$(SuppressAclReset)"
      SuppressAllWarnings="$(LinkerSuppressAllWarnings)"
      SuppressAssemblies="$(SuppressAssemblies)"
      SuppressDefaultAdminSequenceActions="$(SuppressDefaultAdminSequenceActions)"
      SuppressDefaultAdvSequenceActions="$(SuppressDefaultAdvSequenceActions)"
      SuppressDefaultUISequenceActions="$(SuppressDefaultUISequenceActions)"
      SuppressFileHashAndInfo="$(SuppressFileHashAndInfo)"
      SuppressFiles="$(SuppressFiles)"
      SuppressIntermediateFileVersionMatching="$(LinkerSuppressIntermediateFileVersionMatching)"
      SuppressIces="$(SuppressIces)"
      SuppressLayout="$(SuppressLayout)"
      SuppressLocalization="$(SuppressLocalization)"
      SuppressMsiAssemblyTableProcessing="$(SuppressMsiAssemblyTableProcessing)"
      SuppressPdbOutput="$(SuppressPdbOutput)"
      SuppressSchemaValidation="$(LinkerSuppressSchemaValidation)"
      SuppressValidation="$(SuppressValidation)"
      SuppressSpecificWarnings="$(LinkerSuppressSpecificWarnings)"
      SuppressTagSectionIdAttributeOnTuples="$(SuppressTagSectionIdAttributeOnTuples)"
      ToolPath="$(WixToolDir)"
      TreatWarningsAsErrors="$(LinkerTreatWarningsAsErrors)"
      UnreferencedSymbolsFile="$(UnreferencedSymbolsFile)"
      VerboseOutput="$(LinkerVerboseOutput)"
      WixProjectFile="$(ProjectPath)"
      WixVariables="$(WixVariables)" />
  </Target>

  <!--
  ================================================================================================
  UpdateLinkFileWrites

    Reads the bind outputs file(s) output generated during Link to correctly set the @(FileWrites)
    item. Most targets have it easy because they can do a static mapping from inputs to the outputs.
    However, the Link target outputs are determined after a rather complex calculation we call
    linking and binding!

    This target runs independently after Link to ensure that @(FileWrites) is updated even if the
    "Light" task fails.

    [IN]
    Path to bind outputs file(s).

    [OUT]
    @(FileWrites) updated with outputs from bind.
  ================================================================================================
  -->
  <Target
      Name="UpdateLinkFileWrites"
      Condition=" '$(OutputType)' == 'Bundle' or '$(OutputType)' == 'Package' or '$(OutputType)' == 'PatchCreation' or '$(OutputType)' == 'Module' ">

    <ReadLinesFromFile File="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindOutputsFile)">
      <Output TaskParameter="Lines" ItemName="FileWrites"/>
    </ReadLinesFromFile>

    <ItemGroup>
      <FileWrites Include="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindContentsFile)" />
      <FileWrites Include="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindOutputsFile)" />
      <FileWrites Include="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindBuiltOutputsFile)" />
    </ItemGroup>

    <Message Importance="low" Text="Build files after link: @(FileWrites)" />
  </Target>

  <!--
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  AllProjectOutputGroups Section
  //////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////
  -->

  <!--
  ==================================================================================================
  AllProjectOutputGroups - OVERRIDE Target

  ==================================================================================================
  -->
  <Target
      Name="AllProjectOutputGroups"
      DependsOnTargets="
        BuiltProjectOutputGroup;
        DebugSymbolsProjectOutputGroup;
        SourceFilesProjectOutputGroup;
        ContentFilesProjectOutputGroup" />

  <!-- 
  This is the key output for the BuiltProjectOutputGroup and is meant to be read directly from the IDE.
  Reading an item is faster than invoking a target.
  -->
  <ItemGroup>
    <BuiltProjectOutputGroupKeyOutput Include="$(TargetPath)">
      <IsKeyOutput>true</IsKeyOutput>
      <FinalOutputPath>$(TargetPath)</FinalOutputPath>
      <TargetPath>$(TargetFileName)</TargetPath>
    </BuiltProjectOutputGroupKeyOutput>
  </ItemGroup>

  <!--
  ==================================================================================================
  BuiltProjectOutputGroup - OVERRIDE Target
  ==================================================================================================
  -->
  <PropertyGroup>
    <BuiltProjectOutputGroupDependsOn>PrepareForBuild;AssignCultures</BuiltProjectOutputGroupDependsOn>
  </PropertyGroup>
  <Target
    Name="BuiltProjectOutputGroup"
    Outputs="@(BuiltProjectOutputGroupOutput)"
    DependsOnTargets="$(BuiltProjectOutputGroupDependsOn)">

    <!-- Don't add BuiltProjectOutputGroupKeyOutput - to avoid duplicates, we only want to get the updated list of TargetPaths from the TargetPath property below -->

    <!-- Try to read the outputs from the bind outputs text file since that's the output list straight from linker. -->
    <ReadLinesFromFile File="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindOutputsFile)">
      <Output TaskParameter="Lines" ItemName="_BuiltProjectOutputGroupOutputIntermediate"/>
    </ReadLinesFromFile>

    <!-- If we didn't get anything from the bind outputs text file, default to the target path. -->
    <ItemGroup Condition=" '@(_BuiltProjectOutputGroupOutputIntermediate)'=='' ">
      <_BuiltProjectOutputGroupOutputIntermediate Include="$(TargetPath)" />
    </ItemGroup>

    <!-- Convert intermediate items into final items; this way we can get the full path for each item -->
    <ItemGroup>
      <BuiltProjectOutputGroupOutput Include="@(_BuiltProjectOutputGroupOutputIntermediate->'%(FullPath)')">
        <!-- For compatibility with 2.0 -->
        <OriginalItemSpec Condition="'%(_BuiltProjectOutputGroupOutputIntermediate.OriginalItemSpec)' == ''">%(_BuiltProjectOutputGroupOutputIntermediate.FullPath)</OriginalItemSpec>
      </BuiltProjectOutputGroupOutput>
    </ItemGroup>
  </Target>

  <!--
  ==================================================================================================
  DebugSymbolsProjectOutputGroup

    Populates the Debug Symbols project output group.
  ==================================================================================================
  -->
  <PropertyGroup>
    <DebugSymbolsProjectOutputGroupDependsOn>AssignCultures</DebugSymbolsProjectOutputGroupDependsOn>
  </PropertyGroup>
  <Target
    Name="DebugSymbolsProjectOutputGroup"
    Outputs="@(DebugSymbolsProjectOutputGroupOutput)"
    DependsOnTargets="$(DebugSymbolsProjectOutputGroupDependsOn)">

    <!-- Include build output pdb(s).  Different than predefined itemgroup since AssignCultures target may change -->
    <ItemGroup>
      <DebugSymbolsProjectOutputGroupOutput Include="$(TargetPdbPath)" Condition=" '$(SuppressPdbOutput)' != 'true' "/>
    </ItemGroup>
  </Target>


  <!--
  ==================================================================================================
  CopyFilesToOutputDirectory - OVERRIDE Target

  Copy all build outputs, satellites and other necessary files to the final directory.
  ============================================================
  -->
  <Target
      Name="CopyFilesToOutputDirectory">

    <PropertyGroup>
      <!-- By default we're using hard links to copy to the output directory, disabling this could slow the build significantly -->
      <CreateHardLinksForCopyFilesToOutputDirectoryIfPossible Condition=" '$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)' == '' ">true</CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>
    </PropertyGroup>

    <PropertyGroup>
      <CopyBuildOutputToOutputDirectory Condition="'$(CopyBuildOutputToOutputDirectory)'==''">true</CopyBuildOutputToOutputDirectory>
      <CopyOutputSymbolsToOutputDirectory Condition="'$(CopyOutputSymbolsToOutputDirectory)'==''">true</CopyOutputSymbolsToOutputDirectory>
      <FullIntermediateOutputPath>$([System.IO.Path]::GetFullPath($(IntermediateOutputPath)))</FullIntermediateOutputPath>
    </PropertyGroup>

    <!-- Copy the bound files. -->
    <ReadLinesFromFile File="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(BindOutputsFile)">
      <Output TaskParameter="Lines" ItemName="_FullPathToCopy"/>
    </ReadLinesFromFile>

    <ItemGroup>
      <_FullPathToCopy Include="$(TargetPath)" Condition=" '@(_FullPathToCopy)'=='' " />
      <_RelativePath Include="$([MSBuild]::MakeRelative($(FullIntermediateOutputPath), %(_FullPathToCopy.Identity)))" />
    </ItemGroup>

    <Copy
        SourceFiles="@(_RelativePath->'$(IntermediateOutputPath)%(Identity)')"
        DestinationFiles="@(_RelativePath->'$(OutDir)%(Identity)')"
        SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
        OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
        Retries="$(CopyRetryCount)"
        RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
        UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
        Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)' != 'true'"
            >

      <Output TaskParameter="DestinationFiles" ItemName="MainAssembly"/>
      <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>

    </Copy>

    <Message Importance="High" Text="$(MSBuildProjectName) -&gt; $(TargetPath)" Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)'!='true'" />
    <!--<Message Importance="High" Text="$(MSBuildProjectName) -&gt; @(MainAssembly->'%(FullPath)')" Condition="'$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)'!='true'" />-->

    <!-- Copy the debug information file (.pdb), if any
    <Copy
        SourceFiles="@(_DebugSymbolsIntermediatePath)"
        DestinationFiles="@(_DebugSymbolsOutputPath)"
        SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
        OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
        Retries="$(CopyRetryCount)"
        RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
        UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)"
        Condition="'$(_DebugSymbolsProduced)'=='true' and '$(SkipCopyingSymbolsToOutputDirectory)' != 'true' and '$(CopyOutputSymbolsToOutputDirectory)'=='true'">

      <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>

    </Copy>
    -->
  </Target>


  <Import Project="$(WixHarvestTargetsPath)" Condition=" '$(WixHarvestTargetsPath)' != '' and Exists('$(WixHarvestTargetsPath)')" />
  <Import Project="$(WixSigningTargetsPath)" Condition=" '$(WixSigningTargetsPath)' != '' and Exists('$(WixSigningTargetsPath)')" />
  <Import Project="$(LuxTargetsPath)" Condition=" '$(LuxTargetsPath)' != '' and Exists('$(LuxTargetsPath)')" />

  <!-- Extension point: Define CustomAfterWixTargets to a .targets file that you want to include after this file. -->
  <Import Project="$(CustomAfterWixTargets)" Condition=" '$(CustomAfterWixTargets)' != '' and Exists('$(CustomAfterWixTargets)')" />

</Project>
