public ApplyResourceChangeResult <RegistryKeyResource> ApplyChange(
            ApplyResourceChangeInput <RegistryKeyResource> input)
        {
            _log.LogDebug("{method}: ", nameof(ApplyChange));
            _log.LogTrace("->input = {@input}", input);

            _log.LogDebug("  * ....Config: " + JsonConvert.SerializeObject(input.Config, Formatting.Indented));
            _log.LogDebug("  * .....Prior: " + JsonConvert.SerializeObject(input.PriorState, Formatting.Indented));
            _log.LogDebug("  * ...Planned: " + JsonConvert.SerializeObject(input.PlannedState, Formatting.Indented));

            var doDel = false;
            var doAdd = false;

            if (input.PriorState?.Root != input.PlannedState?.Root)
            {
                if (string.IsNullOrEmpty(input.PlannedState?.Root))
                {
                    doDel = true;
                }
                if (string.IsNullOrEmpty(input.PriorState?.Root))
                {
                    doAdd = true;
                }
            }

            if (input.PriorState?.Path != input.PlannedState?.Path)
            {
                if (string.IsNullOrEmpty(input.PlannedState?.Path))
                {
                    doDel = true;
                }
                if (string.IsNullOrEmpty(input.PriorState?.Path))
                {
                    doAdd = true;
                }
            }

            ApplyResourceChangeResult <RegistryKeyResource> result = null;

            if (doDel)
            {
                result = DoDelete(input);
            }
            if (doAdd)
            {
                result = DoCreate(input);
            }

            if (!doDel && !doAdd)
            {
                result = DoUpdate(input);
            }

            _log.LogTrace("<-result = {@result}", result);
            return(result);
        }
        public ApplyResourceChangeResult <FileResource> ApplyChange(
            ApplyResourceChangeInput <FileResource> input)
        {
            _log.LogDebug("{method}: ", nameof(ApplyChange));
            _log.LogTrace("->input = {@input}", input);

            var result = new ApplyResourceChangeResult <FileResource>();

            if (input.ChangeType != ResourceChangeType.Delete)
            {
                result.NewState = new FileResource().CopyArgumentsFrom(input.Config);
            }

            var deleteOld = input.ChangeType != ResourceChangeType.Create &&
                            input.PlannedState?.Path != input.PriorState.Path;
            var createNew = input.ChangeType != ResourceChangeType.Delete &&
                            (input.PlannedState.Path != input.PriorState?.Path ||
                             input.PlannedState.SourceOfContent != input.PriorState?.SourceOfContent);

            if (deleteOld)
            {
                // For Updates & Deletes, remove the old path
                _log.LogInformation("DELETING old path");
                File.Delete(input.PriorState.Path);
            }
            if (createNew)
            {
                // For Creates & Updates, create the new path
                _log.LogInformation("CREATING new path");
                if (!string.IsNullOrEmpty(input.Config.Content))
                {
                    File.WriteAllText(input.Config.Path,
                                      input.Config.Content);
                }
                else if (!string.IsNullOrEmpty(input.Config.ContentBase64))
                {
                    File.WriteAllBytes(input.Config.Path,
                                       Convert.FromBase64String(input.Config.ContentBase64));
                }
                else if (!string.IsNullOrEmpty(input.Config.ContentPath))
                {
                    File.Copy(input.Config.ContentPath, input.Config.Path, true);
                }
                else if (!string.IsNullOrEmpty(input.Config.ContentUrl))
                {
                    using (var wc = new WebClient())
                    {
                        wc.DownloadFile(input.Config.ContentUrl, input.Config.Path);
                    }
                }

                if (input.Config.Appends?.Count > 0)
                {
                    foreach (var cs in input.Config.Appends)
                    {
                        _log.LogInformation("APPENDING new path");
                        WebClient wc     = null;
                        Stream    source = null;
                        if (!string.IsNullOrEmpty(cs.Content))
                        {
                            source = new MemoryStream(Encoding.UTF8.GetBytes(
                                                          cs.Content));
                        }
                        else if (!string.IsNullOrEmpty(cs.ContentBase64))
                        {
                            source = new MemoryStream(Convert.FromBase64String(
                                                          cs.ContentBase64));
                        }
                        else if (!string.IsNullOrEmpty(cs.ContentPath))
                        {
                            source = new FileStream(cs.ContentPath, FileMode.Open);
                        }
                        else if (!string.IsNullOrEmpty(cs.ContentUrl))
                        {
                            wc     = new WebClient();
                            source = wc.OpenRead(cs.ContentUrl);
                        }

                        try
                        {
                            using (source)
                                using (var target = new FileStream(input.Config.Path, FileMode.Append))
                                {
                                    source.CopyTo(target);
                                }
                        }
                        finally
                        {
                            wc?.Dispose();
                        }
                    }
                }
            }

            ComputeState(input.Config, result.NewState, result);

            _log.LogTrace("<-result = {@result}", result);
            return(result);
        }