public void ModifyFile(string filePath, IVariables variables)
        {
            try
            {
                void LogReplacement(string key)
                => log.Verbose(StructuredConfigMessages.StructureFound(key));

                var replaced       = 0;
                var variablesByKey = variables
                                     .Where(v => !OctopusReservedVariablePattern.IsMatch(v.Key))
                                     .DistinctBy(v => v.Key)
                                     .ToDictionary <KeyValuePair <string, string>, string, Func <string?> >(v => v.Key,
                                                                                                            v => () =>
                {
                    LogReplacement(v.Key);
                    replaced++;
                    return(variables.Get(v.Key));
                },
                                                                                                            StringComparer.OrdinalIgnoreCase);

                // Read and transform the input file
                var fileText   = fileSystem.ReadFile(filePath, out var encoding);
                var lineEnding = fileText.GetMostCommonLineEnding();

                var outputEvents   = new List <ParsingEvent>();
                var indentDetector = new YamlIndentDetector();

                using (var reader = new StringReader(fileText))
                {
                    var scanner    = new Scanner(reader, false);
                    var parser     = new Parser(scanner);
                    var classifier = new YamlEventStreamClassifier();
                    (IYamlNode startEvent, string?replacementValue)? structureWeAreReplacing = null;
                    while (parser.MoveNext())
                    {
                        var ev = parser.Current;
                        if (ev == null)
                        {
                            continue;
                        }

                        indentDetector.Process(ev);

                        if (ev is Comment c)
                        {
                            ev = c.RestoreLeadingSpaces();
                        }

                        var node = classifier.Process(ev);

                        if (structureWeAreReplacing == null)
                        {
                            // Not replacing: searching for things to replace, copying events to output.

                            if (node is YamlNode <Scalar> scalar &&
                                variablesByKey.TryGetValue(scalar.Path, out var newValue))
                            {
                                outputEvents.Add(scalar.Event.ReplaceValue(newValue()));
                            }
                            else if (node is YamlNode <MappingStart> mappingStart &&
                                     variablesByKey.TryGetValue(mappingStart.Path, out var mappingReplacement))
                            {
                                structureWeAreReplacing = (mappingStart, mappingReplacement());
                            }
                            else if (node is YamlNode <SequenceStart> sequenceStart &&
                                     variablesByKey.TryGetValue(sequenceStart.Path, out var sequenceReplacement))
                            {
                                structureWeAreReplacing = (sequenceStart, sequenceReplacement());
                            }