protected override async Task <int> ExecuteOnManifest(XDocument document)
        {
            var action = new SetBuildMetaData(this.Verb.Name, this.Verb.Version);

            var executor = new SetBuildMetaDataExecutor(document);

            executor.ValueChanged += (_, change) =>
            {
                if (string.IsNullOrEmpty(change.OldValue) || string.Equals(change.OldValue, change.NewValue, StringComparison.Ordinal))
                {
                    this.Console.WriteSuccess($"Set '{change.Key}' to '{change.NewValue}'").GetAwaiter().GetResult();
                }
                else
                {
                    this.Console.WriteSuccess($"Changed '{change.Key}' from '{change.OldValue}' to '{change.NewValue}'").GetAwaiter().GetResult();
                }
            };

            try
            {
                await executor.Execute(action).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                await this.Console.WriteError($"Build meta data '{this.Verb.Name}' could not be added.").ConfigureAwait(false);

                await this.Console.WriteError(e.Message).ConfigureAwait(false);

                return(StandardExitCodes.ErrorGeneric);
            }

            return(StandardExitCodes.ErrorSuccess);
        }
        public async Task Inject(XDocument manifestContent, BrandingInjectorOverrideOption overwrite = BrandingInjectorOverrideOption.Default)
        {
            var toWrite = new Dictionary <string, string>();
            var toWriteOnlyIfMissing = new Dictionary <string, string>();

            var signToolVersion        = GetVersion("signtool.exe");
            var makePriVersion         = GetVersion("makepri.exe");
            var makeAppxVersion        = GetVersion("makeappx.exe");
            var operatingSystemVersion = NdDll.RtlGetVersion().ToString();
            // ReSharper disable once PossibleNullReferenceException
            var msixHeroVersion = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly()).GetName().Version.ToString();

            toWrite.Add("MsixHero", msixHeroVersion);

            switch (overwrite)
            {
            case BrandingInjectorOverrideOption.Default:
                // prefer existing, with exception of signtool and makeappx that are always re-created.
                toWriteOnlyIfMissing.Add("MakePri.exe", makePriVersion);
                toWrite.Add("SignTool.exe", signToolVersion);
                toWrite.Add("MakeAppx.exe", makeAppxVersion);
                toWriteOnlyIfMissing.Add("OperatingSystem", operatingSystemVersion);
                break;

            case BrandingInjectorOverrideOption.PreferExisting:
                // prefer all existing
                toWriteOnlyIfMissing.Add("MakePri.exe", makePriVersion);
                toWriteOnlyIfMissing.Add("SignTool.exe", signToolVersion);
                toWriteOnlyIfMissing.Add("MakeAppx.exe", makeAppxVersion);
                toWriteOnlyIfMissing.Add("OperatingSystem", operatingSystemVersion);
                break;

            case BrandingInjectorOverrideOption.PreferIncoming:
                // overwrite everything
                toWrite.Add("MakePri.exe", makePriVersion);
                toWrite.Add("SignTool.exe", signToolVersion);
                toWrite.Add("MakeAppx.exe", makeAppxVersion);
                toWrite.Add("OperatingSystem", operatingSystemVersion);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(overwrite), overwrite, null);
            }

            var executor = new SetBuildMetaDataExecutor(manifestContent);

            if (toWrite.Any())
            {
                var action = new SetBuildMetaData(toWrite)
                {
                    OnlyCreateNew = false
                };

                await executor.Execute(action).ConfigureAwait(false);
            }

            if (toWriteOnlyIfMissing.Any())
            {
                var action = new SetBuildMetaData(toWriteOnlyIfMissing)
                {
                    OnlyCreateNew = true
                };

                await executor.Execute(action).ConfigureAwait(false);
            }
        }