diff --git a/src/NuGet.Core/NuGet.Build.Tasks/GenerateTemporaryTargetAssembly2.cs b/src/NuGet.Core/NuGet.Build.Tasks/GenerateTemporaryTargetAssembly2.cs
new file mode 100644
index 00000000000..d92d6b4ef03
--- /dev/null
+++ b/src/NuGet.Core/NuGet.Build.Tasks/GenerateTemporaryTargetAssembly2.cs
@@ -0,0 +1,528 @@
+
+//---------------------------------------------------------------------------
+//
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+//
+// Description: This is a MSBuild task which generates a temporary target assembly
+// if current project contains a xaml file with local-type-reference.
+//
+// It generates a temporary project file and then call build-engine
+// to compile it.
+//
+// The new project file will replace all the Reference Items with the
+// resolved ReferenctPath, add all the generated code file into Compile
+// Item list.
+//
+// History:
+// 05/10/05: weibz Created.
+// 11/03/17: support NuGet PackageReference properly in temporary assembly by enabling .g.targets and .g.props to be
+// properly included, despite the project file name change.
+//
+//---------------------------------------------------------------------------
+
+using System;
+using System.IO;
+using System.Collections;
+
+using System.Globalization;
+using System.Diagnostics;
+using System.Reflection;
+using System.Resources;
+using System.Xml;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.BuildEngine;
+
+using MS.Utility;
+using MS.Internal.Tasks;
+
+// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler.
+// We first need to disable warnings about unknown message numbers and unknown pragmas.
+#pragma warning disable 1634, 1691
+
+namespace Microsoft.Build.Tasks.Windows
+{
+ #region GenerateTemporaryTargetAssembly2 Task class
+
+ ///
+ /// This task is used to generate a temporary target assembly. It generates
+ /// a temporary project file and then compile it.
+ ///
+ /// The generated project file is based on current project file, with below
+ /// modification:
+ ///
+ /// A: Add the generated code files (.g.cs) to Compile Item list.
+ /// B: Replace Reference Item list with ReferenctPath item list.
+ /// So that it doesn't need to rerun time-consuming tatk
+ /// ResolveAssemblyReference (RAR) again.
+ ///
+ ///
+ public sealed class GenerateTemporaryTargetAssembly2 : Task
+ {
+ //------------------------------------------------------
+ //
+ // Constructors
+ //
+ //------------------------------------------------------
+
+ #region Constructors
+
+ ///
+ /// Constrcutor
+ ///
+ public GenerateTemporaryTargetAssembly2()
+ {
+ }
+
+ #endregion Constructors
+
+ //------------------------------------------------------
+ //
+ // Public Methods
+ //
+ //------------------------------------------------------
+
+ #region Public Methods
+
+ ///
+ /// ITask Execute method
+ ///
+ ///
+ public override bool Execute()
+ {
+ bool retValue = true;
+
+ // Verification
+ try
+ {
+ XmlDocument xmlProjectDoc = null;
+
+ xmlProjectDoc = new XmlDocument();
+ xmlProjectDoc.Load(CurrentProject);
+
+ //
+ // remove all the WinFX specific item lists
+ // ApplicationDefinition, Page, MarkupResource and Resource
+ //
+
+ RemoveItemsByName(xmlProjectDoc, APPDEFNAME);
+ RemoveItemsByName(xmlProjectDoc, PAGENAME);
+ RemoveItemsByName(xmlProjectDoc, MARKUPRESOURCENAME);
+ RemoveItemsByName(xmlProjectDoc, RESOURCENAME);
+
+ // Replace the Reference Item list with ReferencePath
+
+ RemoveItemsByName(xmlProjectDoc, REFERENCETYPENAME);
+ AddNewItems(xmlProjectDoc, ReferencePathTypeName, ReferencePath);
+
+ // Add GeneratedCodeFiles to Compile item list.
+ AddNewItems(xmlProjectDoc, CompileTypeName, GeneratedCodeFiles);
+
+
+ // Create a random file name
+ // This can fix the problem of project cache in VS.NET environment.
+ //
+
+ // GetRandomFileName( ) could return any possible file name and extension, but
+ // some file extension has special meaning in MSBUILD system, such as a ".sln"
+ // means the file is a solution file with special file format. Since the temporary
+ // file is just for a project, we can use a fixed extension here, but the basic
+ // file name is still random which can fix above VS.NET bug.
+ //
+ string randProjPath = Path.ChangeExtension(Path.GetRandomFileName(), Path.GetExtension(CurrentProject));
+
+ // Save the xmlDocument content into the temporary project file.
+ xmlProjectDoc.Save(randProjPath);
+
+ //
+ // Invoke MSBUILD engine to build this temporary project file.
+ //
+
+ Hashtable globalProperties = new Hashtable(3);
+
+ // Add AssemblyName and IntermediateOutputPath to the global property list
+ globalProperties[intermediateOutputPathPropertyName] = IntermediateOutputPath;
+ globalProperties[assemblyNamePropertyName] = AssemblyName;
+ globalProperties[originalProjectNamePropertyName] = Path.GetFileNameWithoutExtension(CurrentProject);
+
+ retValue = BuildEngine.BuildProjectFile(randProjPath, new string[] { CompileTargetName }, globalProperties, null);
+
+ try
+ {
+ // Delete the random project file from disk unless an advanced user wants to keep it around to help debug failures.
+ if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envVarWPFDoNotDeleteTemporaryProject)))
+ {
+ File.Delete(randProjPath);
+ }
+ }
+ catch (IOException e)
+ {
+ // Failure to delete the file is a non fatal error
+ Log.LogWarningFromException(e);
+ }
+
+ }
+#pragma warning disable 6500
+ catch (Exception e)
+ {
+ Log.LogErrorFromException(e);
+ retValue = false;
+ }
+#pragma warning restore 6500
+
+ return retValue;
+ }
+ #endregion Public Methods
+
+ //------------------------------------------------------
+ //
+ // Public Properties
+ //
+ //------------------------------------------------------
+
+ #region Public Properties
+
+ ///
+ /// CurrentProject
+ /// The full path of current project file.
+ ///
+ [Required]
+ public string CurrentProject
+ {
+ get { return _currentProject; }
+ set { _currentProject = value; }
+ }
+
+ ///
+ /// MSBuild Binary Path.
+ /// This is required for Project to work correctly.
+ ///
+ [Required]
+ public string MSBuildBinPath
+ {
+ get { return _msbuildBinPath; }
+ set { _msbuildBinPath = value; }
+ }
+
+ ///
+ /// GeneratedCodeFiles
+ /// A list of generated code files, it could be empty.
+ /// The list will be added to the Compile item list in new generated project file.
+ ///
+ public ITaskItem[] GeneratedCodeFiles
+ {
+ get { return _generatedCodeFiles; }
+ set { _generatedCodeFiles = value; }
+ }
+
+ ///
+ /// CompileTypeName
+ /// The appropriate item name which can be accepted by managed compiler task.
+ /// It is "Compile" for now.
+ ///
+ /// Adding this property is to make the type name configurable, if it is changed,
+ /// No code is required to change in this task, but set a new type name in project file.
+ ///
+ [Required]
+ public string CompileTypeName
+ {
+ get { return _compileTypeName; }
+ set { _compileTypeName = value; }
+ }
+
+
+ ///
+ /// ReferencePath
+ /// A list of resolved reference assemblies.
+ /// The list will replace the original Reference item list in generated project file.
+ ///
+ public ITaskItem[] ReferencePath
+ {
+ get { return _referencePath; }
+ set { _referencePath = value; }
+ }
+
+ ///
+ /// ReferencePathTypeName
+ /// The appropriate item name which is used to keep the Reference list in managed compiler task.
+ /// It is "ReferencePath" for now.
+ ///
+ /// Adding this property is to make the type name configurable, if it is changed,
+ /// No code is required to change in this task, but set a new type name in project file.
+ ///
+ [Required]
+ public string ReferencePathTypeName
+ {
+ get { return _referencePathTypeName; }
+ set { _referencePathTypeName = value; }
+ }
+
+
+ ///
+ /// IntermediateOutputPath
+ ///
+ /// The value which is set to IntermediateOutputPath property in current project file.
+ ///
+ /// Passing this value explicitly is to make sure to generate temporary target assembly
+ /// in expected directory.
+ ///
+ [Required]
+ public string IntermediateOutputPath
+ {
+ get { return _intermediateOutputPath; }
+ set { _intermediateOutputPath = value; }
+ }
+
+ ///
+ /// AssemblyName
+ ///
+ /// The value which is set to AssemblyName property in current project file.
+ /// Passing this value explicitly is to make sure to generate the expected
+ /// temporary target assembly.
+ ///
+ ///
+ [Required]
+ public string AssemblyName
+ {
+ get { return _assemblyName; }
+ set { _assemblyName = value; }
+ }
+
+ ///
+ /// CompileTargetName
+ ///
+ /// The msbuild target name which is used to generate assembly from source code files.
+ /// Usually it is "CoreCompile"
+ ///
+ ///
+ [Required]
+ public string CompileTargetName
+ {
+ get { return _compileTargetName; }
+ set { _compileTargetName = value; }
+ }
+
+ #endregion Public Properties
+
+ //------------------------------------------------------
+ //
+ // Private Methods
+ //
+ //------------------------------------------------------
+
+ #region Private Methods
+
+ //
+ // Remove specific items from project file. Every item should be under an ItemGroup.
+ //
+ private void RemoveItemsByName(XmlDocument xmlProjectDoc, string sItemName)
+ {
+ if (xmlProjectDoc == null || String.IsNullOrEmpty(sItemName))
+ {
+ // When the parameters are not valid, simply return it, instead of throwing exceptions.
+ return;
+ }
+
+ //
+ // The project file format is always like below:
+ //
+ //
+ //
+ // ......
+ //
+ //
+ // ...
+ //
+ //
+ // ....
+ //
+ //
+ // ....
+ //
+ // ...
+ //
+ //
+ // ...
+ //
+ //
+ //
+ //
+ // The order of children nodes under Project Root element is random
+ //
+
+ XmlNode root = xmlProjectDoc.DocumentElement;
+
+ if (root.HasChildNodes == false)
+ {
+ // If there is no child element in this project file, just return immediatelly.
+ return;
+ }
+
+ for (int i = 0; i < root.ChildNodes.Count; i++)
+ {
+ XmlElement nodeGroup = root.ChildNodes[i] as XmlElement;
+
+ if (nodeGroup != null && String.Compare(nodeGroup.Name, ITEMGROUP_NAME, StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ //
+ // This is ItemGroup element.
+ //
+ if (nodeGroup.HasChildNodes)
+ {
+ ArrayList itemToRemove = new ArrayList();
+
+ for (int j = 0; j < nodeGroup.ChildNodes.Count; j++)
+ {
+ XmlElement nodeItem = nodeGroup.ChildNodes[j] as XmlElement;
+
+ if (nodeItem != null && String.Compare(nodeItem.Name, sItemName, StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ // This is the item that need to remove.
+ // Add it into the temporary array list.
+ // Don't delete it here, since it would affect the ChildNodes of parent element.
+ //
+ itemToRemove.Add(nodeItem);
+ }
+ }
+
+ //
+ // Now it is the right time to delete the elements.
+ //
+ if (itemToRemove.Count > 0)
+ {
+ foreach (object node in itemToRemove)
+ {
+ XmlElement item = node as XmlElement;
+
+ //
+ // Remove this item from its parent node.
+ // the parent node should be nodeGroup.
+ //
+ if (item != null)
+ {
+ nodeGroup.RemoveChild(item);
+ }
+ }
+ }
+ }
+
+ //
+ // Removed all the items with given name from this item group.
+ //
+ // Continue the loop for the next ItemGroup.
+ }
+
+ } // end of "for i" statement.
+
+ }
+
+ //
+ // Add a list of files into an Item in the project file, the ItemName is specified by sItemName.
+ //
+ private void AddNewItems(XmlDocument xmlProjectDoc, string sItemName, ITaskItem[] pItemList)
+ {
+ if (xmlProjectDoc == null || String.IsNullOrEmpty(sItemName) || pItemList == null)
+ {
+ // When the parameters are not valid, simply return it, instead of throwing exceptions.
+ return;
+ }
+
+ XmlNode root = xmlProjectDoc.DocumentElement;
+
+ // Create a new ItemGroup element
+ XmlNode nodeItemGroup = xmlProjectDoc.CreateElement(ITEMGROUP_NAME, root.NamespaceURI);
+
+ // Append this new ItemGroup item into the list of children of the document root.
+ root.AppendChild(nodeItemGroup);
+
+ XmlElement embedItem = null;
+
+ for (int i = 0; i < pItemList.Length; i++)
+ {
+ // Create an element for the given sItemName
+ XmlElement nodeItem = xmlProjectDoc.CreateElement(sItemName, root.NamespaceURI);
+
+ // Create an Attribute "Include"
+ XmlAttribute attrInclude = xmlProjectDoc.CreateAttribute(INCLUDE_ATTR_NAME);
+
+ ITaskItem pItem = pItemList[i];
+
+ // Set the value for Include attribute.
+ attrInclude.Value = pItem.ItemSpec;
+
+ // Add the attribute to current item node.
+ nodeItem.SetAttributeNode(attrInclude);
+
+ if (TRUE == pItem.GetMetadata(EMBEDINTEROPTYPES))
+ {
+ embedItem = xmlProjectDoc.CreateElement(EMBEDINTEROPTYPES, root.NamespaceURI);
+ embedItem.InnerText = TRUE;
+ nodeItem.AppendChild(embedItem);
+ }
+
+ string aliases = pItem.GetMetadata(ALIASES);
+ if (!String.IsNullOrEmpty(aliases))
+ {
+ embedItem = xmlProjectDoc.CreateElement(ALIASES, root.NamespaceURI);
+ embedItem.InnerText = aliases;
+ nodeItem.AppendChild(embedItem);
+ }
+
+ // Add current item node into the children list of ItemGroup
+ nodeItemGroup.AppendChild(nodeItem);
+ }
+ }
+
+ #endregion Private Methods
+
+
+ //------------------------------------------------------
+ //
+ // Private Fields
+ //
+ //------------------------------------------------------
+
+ #region Private Fields
+
+ private string _currentProject = String.Empty;
+
+ private ITaskItem[] _generatedCodeFiles;
+ private ITaskItem[] _referencePath;
+
+ private string _referencePathTypeName;
+ private string _compileTypeName;
+
+ private string _msbuildBinPath;
+
+ private string _intermediateOutputPath;
+ private string _assemblyName;
+ private string _compileTargetName;
+
+ private const string intermediateOutputPathPropertyName = "IntermediateOutputPath";
+ private const string assemblyNamePropertyName = "AssemblyName";
+ private const string originalProjectNamePropertyName = "_OriginalProjectName";
+
+ private const string envVarWPFDoNotDeleteTemporaryProject = "WPF_DoNotDeleteTemporaryProject";
+
+ private const string ALIASES = "Aliases";
+ private const string REFERENCETYPENAME = "Reference";
+ private const string EMBEDINTEROPTYPES = "EmbedInteropTypes";
+ private const string APPDEFNAME = "ApplicationDefinition";
+ private const string PAGENAME = "Page";
+ private const string MARKUPRESOURCENAME = "MarkupResource";
+ private const string RESOURCENAME = "Resource";
+
+ private const string ITEMGROUP_NAME = "ItemGroup";
+ private const string INCLUDE_ATTR_NAME = "Include";
+
+ private const string TRUE = "True";
+
+ #endregion Private Fields
+
+ }
+
+ #endregion GenerateProjectForLocalTypeReference Task class
+}
diff --git a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
index 3e0a3b87fb6..1703dcb0ca0 100644
--- a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
+++ b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
@@ -82,6 +82,7 @@ Copyright (c) .NET Foundation. All rights reserved.
+