protected override void ExecuteCore()

in src/Tasks/Microsoft.NET.Build.Tasks/JoinItems.cs [40:131]


        protected override void ExecuteCore()
        {
            bool useLeftItemSpec = false;
            bool useRightItemSpec = false;
            if (string.Equals(ItemSpecToUse, "Left", StringComparison.OrdinalIgnoreCase))
            {
                useLeftItemSpec = true;
            }
            else if (string.Equals(ItemSpecToUse, "Right", StringComparison.OrdinalIgnoreCase))
            {
                useRightItemSpec = true;
            }
            else if (!string.IsNullOrEmpty(ItemSpecToUse))
            {
                throw new BuildErrorException(Strings.InvalidItemSpecToUse, ItemSpecToUse);
            }

            bool useAllLeftMetadata = LeftMetadata != null && LeftMetadata.Length == 1 && LeftMetadata[0] == "*";
            bool useAllRightMetadata = RightMetadata != null && RightMetadata.Length == 1 && RightMetadata[0] == "*";

            JoinResult = Left.Join(Right,
                item => GetKeyValue(LeftKey, item),
                item => GetKeyValue(RightKey, item),
                (left, right) =>
                {
                    //  If including all metadata from left items and none from right items, just return left items directly
                    if (useAllLeftMetadata &&
                        (string.IsNullOrEmpty(LeftKey) || useLeftItemSpec) &&
                        (RightMetadata == null || RightMetadata.Length == 0))
                    {
                        return left;
                    }

                    //  If including all metadata from right items and none from left items, just return the right items directly
                    if (useAllRightMetadata &&
                        (string.IsNullOrEmpty(RightKey) || useRightItemSpec) &&
                        (LeftMetadata == null || LeftMetadata.Length == 0))
                    {
                        return right;
                    }

                    string resultItemSpec;
                    if (useLeftItemSpec)
                    {
                        resultItemSpec = left.ItemSpec;
                    }
                    else if (useRightItemSpec)
                    {
                        resultItemSpec = right.ItemSpec;
                    }
                    else
                    {
                        resultItemSpec = GetKeyValue(LeftKey, left);
                    }

                    var ret = new TaskItem(resultItemSpec);

                    //  Weird ordering here is to prefer left metadata in all cases, as CopyToMetadata doesn't overwrite any existing metadata
                    if (useAllLeftMetadata)
                    {
                        //  CopyMetadata adds an OriginalItemSpec, which we don't want.  So we subsequently remove it
                        left.CopyMetadataTo(ret);
                        ret.RemoveMetadata(MetadataKeys.OriginalItemSpec);
                    }

                    if (!useAllRightMetadata && RightMetadata != null)
                    {
                        foreach (string name in RightMetadata)
                        {
                            ret.SetMetadata(name, right.GetMetadata(name));
                        }
                    }

                    if (!useAllLeftMetadata && LeftMetadata != null)
                    {
                        foreach (string name in LeftMetadata)
                        {
                            ret.SetMetadata(name, left.GetMetadata(name));
                        }
                    }

                    if (useAllRightMetadata)
                    {
                        //  CopyMetadata adds an OriginalItemSpec, which we don't want.  So we subsequently remove it
                        right.CopyMetadataTo(ret);
                        ret.RemoveMetadata(MetadataKeys.OriginalItemSpec);
                    }

                    return (ITaskItem)ret;
                },
                StringComparer.OrdinalIgnoreCase).ToArray();            
        }