private void CreateResolvedReferenceItem()

in src/Tasks/ResolveSDKReference.cs [1410:1767]


            private void CreateResolvedReferenceItem(string targetConfiguration, string targetArchitecture, HashSet<string> sdkNamesOnReferenceItems, string targetPlatformIdentifier, Version targetPlatformVersion, Version targetPlatformVersionFromItem, string projectName, bool enableMaxPlatformVersionEmptyWarning)
            {
                // Make output item to send to the project file which represents a resolve SDKReference
                ResolvedItem = new TaskItem(ResolvedPath);
                ResolvedItem.SetMetadata("SDKName", SDKName);

                if (!String.IsNullOrEmpty(ProductFamilyName))
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.ProductFamilyName, ProductFamilyName);
                }

                // Copy existing metadata onto the output item
                ReferenceItem.CopyMetadataTo(ResolvedItem);

                ResolvedItem.SetMetadata("SupportsMultipleVersions", _supportsMultipleVersions.ToString());

                // If no architecture and configuration is passed in then default to retail neutral
                targetArchitecture = String.IsNullOrEmpty(targetArchitecture) ? NeutralArch : targetArchitecture;
                targetConfiguration = String.IsNullOrEmpty(targetConfiguration) ? Retail : targetConfiguration;

                // Check to see if there was metadata on the original reference item, if there is then that wins.
                string sdkConfiguration = ReferenceItem.GetMetadata(TargetedSDKConfiguration);
                sdkConfiguration = sdkConfiguration.Length > 0 ? sdkConfiguration : targetConfiguration;

                string sdkArchitecture = ReferenceItem.GetMetadata(TargetedSDKArchitecture).Length > 0 ? ReferenceItem.GetMetadata(TargetedSDKArchitecture) : targetArchitecture;
                sdkArchitecture = sdkArchitecture.Length > 0 ? sdkArchitecture : targetArchitecture;

                // Configuration is somewhat special, if Release is passed in me want to convert it to Retail and set that on the resulting output item.
                sdkConfiguration = sdkConfiguration.Equals("Release", StringComparison.OrdinalIgnoreCase) ? Retail : sdkConfiguration;

                sdkArchitecture = sdkArchitecture.Equals("msil", StringComparison.OrdinalIgnoreCase) ? NeutralArch : sdkArchitecture;
                sdkArchitecture = sdkArchitecture.Equals("AnyCPU", StringComparison.OrdinalIgnoreCase) ? NeutralArch : sdkArchitecture;
                sdkArchitecture = sdkArchitecture.Equals("Any CPU", StringComparison.OrdinalIgnoreCase) ? NeutralArch : sdkArchitecture;
                sdkArchitecture = sdkArchitecture.Equals("amd64", StringComparison.OrdinalIgnoreCase) ? X64Arch : sdkArchitecture;

                ResolvedItem.SetMetadata(TargetedSDKConfiguration, sdkConfiguration);
                ResolvedItem.SetMetadata(TargetedSDKArchitecture, sdkArchitecture);

                // Print out a message indicating what our targeted sdk configuration and architecture is so users know what the reference is targeting.
                AddStatusMessage("ResolveSDKReference.TargetedConfigAndArchitecture", sdkConfiguration, sdkArchitecture);

                string[] supportedArchitectures = null;
                if (SupportedArchitectures != null && SupportedArchitectures.Length > 0)
                {
                    supportedArchitectures = SupportedArchitectures.Split(s_supportedArchitecturesSplitChars, StringSplitOptions.RemoveEmptyEntries);
                }

                if (supportedArchitectures != null)
                {
                    bool foundTargetArchitecture = false;

                    // SupportedArchitectures will usually only contain a handful of elements therefore putting this into a hashtable or dictionary would not likely give us much performance improvement.
                    foreach (string architecture in supportedArchitectures)
                    {
                        if (architecture.Equals(sdkArchitecture, StringComparison.OrdinalIgnoreCase))
                        {
                            foundTargetArchitecture = true;
                            break;
                        }
                    }

                    if (!foundTargetArchitecture)
                    {
                        string remappedArchitecture = sdkArchitecture.Equals(NeutralArch, StringComparison.OrdinalIgnoreCase) ? AnyCPUArch : sdkArchitecture;
                        string supportedArchList = String.Empty;

                        for (int i = 0; i < supportedArchitectures.Length; i++)
                        {
                            supportedArchList += supportedArchitectures[i].Equals(NeutralArch, StringComparison.OrdinalIgnoreCase) ? AnyCPUArch : supportedArchitectures[i];

                            // only put a comma after the first if there is more that one and do not put one after the end
                            if (supportedArchitectures.Length > 1 && i != supportedArchitectures.Length - 1)
                            {
                                supportedArchList += SupportedArchitectureJoinDelimiter;
                            }
                        }

                        AddResolutionErrorOrWarning("ResolveSDKReference.TargetArchitectureNotSupported", remappedArchitecture, SDKName, supportedArchList);
                    }
                }

                if (!String.IsNullOrEmpty(MaxPlatformVersion))
                {
                    Version maxPlatformVersionAsVersion;

                    if (System.Version.TryParse(MaxPlatformVersion, out maxPlatformVersionAsVersion) && (maxPlatformVersionAsVersion < targetPlatformVersion))
                    {
                        AddResolutionWarning("ResolveSDKReference.MaxPlatformVersionLessThanTargetPlatformVersion", projectName, DisplayName, Version, targetPlatformIdentifier, MaxPlatformVersion, targetPlatformIdentifier, targetPlatformVersion.ToString());
                    }
                }
                else if (enableMaxPlatformVersionEmptyWarning && targetPlatformVersionFromItem != null && targetPlatformVersionFromItem < targetPlatformVersion)
                {
                    AddResolutionWarning("ResolveSDKReference.MaxPlatformVersionNotSpecified", projectName, DisplayName, Version, targetPlatformIdentifier, targetPlatformVersionFromItem.ToString(), targetPlatformIdentifier, targetPlatformVersion.ToString());
                }

                if (!String.IsNullOrEmpty(TargetPlatform) && !String.Equals(targetPlatformIdentifier, TargetPlatform))
                {
                    AddResolutionErrorOrWarning("ResolveSDKReference.TargetPlatformIdentifierDoesNotMatch", projectName, DisplayName, Version, targetPlatformIdentifier, TargetPlatform);
                }

                if (!String.IsNullOrEmpty(TargetPlatformMinVersion))
                {
                    Version targetPlatformMinVersionAsVersion;

                    if (System.Version.TryParse(TargetPlatformMinVersion, out targetPlatformMinVersionAsVersion) && (targetPlatformVersion < targetPlatformMinVersionAsVersion))
                    {
                        AddResolutionErrorOrWarning("ResolveSDKReference.PlatformVersionIsLessThanMinVersion", projectName, DisplayName, Version, targetPlatformVersion.ToString(), targetPlatformMinVersionAsVersion.ToString());
                    }
                }

                if (String.Equals(NeutralArch, sdkArchitecture, StringComparison.OrdinalIgnoreCase) && !String.IsNullOrEmpty(SupportPrefer32Bit) && _prefer32BitFromProject)
                {
                    bool supportPrefer32Bit = true;
                    bool.TryParse(SupportPrefer32Bit, out supportPrefer32Bit);

                    if (!supportPrefer32Bit)
                    {
                        AddResolutionErrorOrWarning("ResolveSDKReference.Prefer32BitNotSupportedWithNeutralProject", SDKName);
                    }
                }

                // The SDKManifest may have had a number of frameworkidentity entries inside of it. We want to match the one
                // which has the correct configuration and architecture. If a perfect match cannot be found 
                // then we will look for ones that declare only the configuration. If that cannot be found we just try and find an element that only is "FrameworkIdentity".
                if (String.IsNullOrEmpty(FrameworkIdentity))
                {
                    if (FrameworkIdentitiesFromManifest.Count > 0)
                    {
                        // Try and find a framework identity that matches on both the configuration and architecture "FrameworkIdentity-<Config>-<Arch>"
                        FrameworkIdentity = null;
                        string frameworkIdentityKey = String.Format(CultureInfo.InvariantCulture, "{0}-{1}-{2}", SDKManifest.Attributes.FrameworkIdentity, sdkConfiguration, sdkArchitecture);
                        FrameworkIdentity = FindFrameworkIdentity(frameworkIdentityKey);

                        // Try and find a framework identity that matches on the configuration , Element must be named "FrameworkIdentity-<Config>" only.
                        if (FrameworkIdentity == null)
                        {
                            frameworkIdentityKey = String.Format(CultureInfo.InvariantCulture, "{0}-{1}", SDKManifest.Attributes.FrameworkIdentity, sdkConfiguration);
                            FrameworkIdentity = FindFrameworkIdentity(frameworkIdentityKey);
                        }

                        // See if there is an element just called "FrameworkIdentity"
                        if (FrameworkIdentity == null)
                        {
                            frameworkIdentityKey = SDKManifest.Attributes.FrameworkIdentity;
                            FrameworkIdentity = FindFrameworkIdentity(frameworkIdentityKey);
                        }

                        if (FrameworkIdentity == null)
                        {
                            AddResolutionErrorOrWarning("ResolveSDKReference.NoMatchingFrameworkIdentity", _sdkManifestPath, sdkConfiguration, sdkArchitecture);
                        }
                        else
                        {
                            ResolvedItem.SetMetadata(SDKManifest.Attributes.FrameworkIdentity, FrameworkIdentity);
                        }
                    }
                    else
                    {
                        AddStatusMessage("ResolveSDKReference.NoFrameworkIdentitiesFound");
                    }
                }
                else
                {
                    AddStatusMessage("ResolveSDKReference.FoundFrameworkIdentity", FrameworkIdentity);
                }

                // Print out if we are a platform SDK
                if (!String.IsNullOrEmpty(PlatformIdentity))
                {
                    AddStatusMessage("ResolveSDKReference.PlatformSDK", PlatformIdentity);
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.PlatformIdentity, PlatformIdentity);
                }

                // The SDKManifest may have had a number of AppxLocation entries inside of it. We want to return the set of unique architectures for a selected configuration.
                if (String.IsNullOrEmpty(AppxLocation))
                {
                    if (AppxLocationsFromManifest.Count > 0)
                    {
                        AppxLocation = null;

                        // For testing especially it's nice to have a set order of what the generated appxlocation string will be at the end
                        SortedDictionary<string, string> architectureLocations = new SortedDictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
                        List<string> appxLocationComponents = new List<string>();

                        foreach (var appxLocation in AppxLocationsFromManifest)
                        {
                            if (!String.IsNullOrEmpty(appxLocation.Key))
                            {
                                string[] appxComponents = appxLocation.Key.Split(s_appxSplitChar, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray();

                                // The first component needs to be appx
                                if (!String.Equals("Appx", appxComponents[0], StringComparison.OrdinalIgnoreCase))
                                {
                                    continue;
                                }

                                string configurationComponent = null;
                                string architectureComponent = null;
                                switch (appxComponents.Length)
                                {
                                    case 1:
                                        architectureComponent = NeutralArch;
                                        break;
                                    case 2:
                                        configurationComponent = appxComponents[1];
                                        architectureComponent = NeutralArch;

                                        // If the configuration is not debug or retail then we will assume it is an architecture
                                        if (!(configurationComponent.Equals(Debug, StringComparison.OrdinalIgnoreCase) || configurationComponent.Equals(Retail, StringComparison.OrdinalIgnoreCase)))
                                        {
                                            configurationComponent = null;
                                            architectureComponent = appxComponents[1];
                                        }

                                        break;
                                    case 3:
                                        configurationComponent = appxComponents[1];
                                        architectureComponent = appxComponents[2];
                                        break;
                                    default:
                                        // Not one of the cases we expect, just skip it
                                        continue;
                                }

                                bool containsKey = architectureLocations.ContainsKey(architectureComponent);

                                // If we have not seen this architecture before (and it has a compatible configuration with what we are targeting) then add it. 
                                // Also, replace the entry if we have already added an entry for a non configuration specific entry and we now have a configuration specific entry that matches what we are targeting.
                                if ((configurationComponent == null && !containsKey) || (configurationComponent != null && configurationComponent.Equals(sdkConfiguration, StringComparison.OrdinalIgnoreCase)))
                                {
                                    AddStatusMessage("ResolveSDKReference.FoundAppxLocation", appxLocation.Key + "=" + appxLocation.Value);

                                    if (containsKey)
                                    {
                                        AddStatusMessage("ResolveSDKReference.ReplaceAppxLocation", architectureComponent, architectureLocations[architectureComponent], appxLocation.Value);
                                    }

                                    architectureLocations[architectureComponent] = appxLocation.Value;
                                }
                            }
                        }

                        foreach (var location in architectureLocations)
                        {
                            appxLocationComponents.Add(location.Key);
                            appxLocationComponents.Add(location.Value);
                        }

                        if (appxLocationComponents.Count > 0)
                        {
                            AppxLocation = String.Join("|", appxLocationComponents.ToArray());
                        }

                        if (AppxLocation == null)
                        {
                            AddResolutionErrorOrWarning("ResolveSDKReference.NoMatchingAppxLocation", _sdkManifestPath, sdkConfiguration, sdkArchitecture);
                        }
                        else
                        {
                            ResolvedItem.SetMetadata(SDKManifest.Attributes.AppxLocation, AppxLocation);
                        }
                    }
                    else
                    {
                        AddStatusMessage("ResolveSDKReference.NoAppxLocationsFound");
                    }
                }
                else
                {
                    AddStatusMessage("ResolveSDKReference.FoundAppxLocation", AppxLocation);
                }

                ResolvedItem.SetMetadata("SimpleName", SimpleName);
                ResolvedItem.SetMetadata("Version", Version);

                // Check to see if the copy local metadata has been set in the project file.
                bool result;
                bool hasExpandReferenceAssemblies = bool.TryParse(ReferenceItem.GetMetadata(SDKManifest.Attributes.ExpandReferenceAssemblies), out result);
                bool hasCopyRedist = bool.TryParse(ReferenceItem.GetMetadata(SDKManifest.Attributes.CopyRedist), out result);
                bool hasCopyLocalExpandedReferenceAssemblies = bool.TryParse(ReferenceItem.GetMetadata(SDKManifest.Attributes.CopyLocalExpandedReferenceAssemblies), out result);

                bool referenceItemHasSDKName = sdkNamesOnReferenceItems.Contains(SDKName);

                if (SDKType != SDKType.Unspecified)
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.SDKType, SDKType.ToString());
                }

                if (!String.IsNullOrEmpty(DisplayName))
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.DisplayName, DisplayName);
                }

                // Could be null or empty depending if blank metadata was set or not.
                bool frameworkSDK = SDKType == SDKType.Framework || !String.IsNullOrEmpty(FrameworkIdentity);
                bool hasPlatformIdentity = SDKType == SDKType.Platform || !String.IsNullOrEmpty(PlatformIdentity);

                if (!hasExpandReferenceAssemblies)
                {
                    if (referenceItemHasSDKName)
                    {
                        ResolvedItem.SetMetadata(SDKManifest.Attributes.ExpandReferenceAssemblies, "false");
                    }
                    else
                    {
                        ResolvedItem.SetMetadata(SDKManifest.Attributes.ExpandReferenceAssemblies, "true");
                    }
                }

                if (!hasCopyRedist)
                {
                    if (frameworkSDK || hasPlatformIdentity)
                    {
                        ResolvedItem.SetMetadata(SDKManifest.Attributes.CopyRedist, "false");
                    }
                    else
                    {
                        ResolvedItem.SetMetadata(SDKManifest.Attributes.CopyRedist, "true");
                    }
                }

                if (!hasCopyLocalExpandedReferenceAssemblies)
                {
                    if (frameworkSDK || referenceItemHasSDKName || hasPlatformIdentity)
                    {
                        ResolvedItem.SetMetadata(SDKManifest.Attributes.CopyLocalExpandedReferenceAssemblies, "false");
                    }
                    else
                    {
                        ResolvedItem.SetMetadata(SDKManifest.Attributes.CopyLocalExpandedReferenceAssemblies, "true");
                    }
                }

                if (!String.IsNullOrEmpty(CopyRedistToSubDirectory))
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.CopyRedistToSubDirectory, CopyRedistToSubDirectory);
                }

                if (!String.IsNullOrEmpty(MaxPlatformVersion))
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.MaxPlatformVersion, MaxPlatformVersion);
                }

                if (!String.IsNullOrEmpty(MinOSVersion))
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.MinOSVersion, MinOSVersion);
                }

                if (!String.IsNullOrEmpty(MaxOSVersionTested))
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.MaxOSVersionTested, MaxOSVersionTested);
                }

                if (!String.IsNullOrEmpty(MoreInfo))
                {
                    ResolvedItem.SetMetadata(SDKManifest.Attributes.MoreInfo, MoreInfo);
                }
            }