protected (CalamariResult result, IVariables variables) RunScript(string scriptName,
                                                                          Dictionary <string, string> additionalVariables  = null,
                                                                          Dictionary <string, string> additionalParameters = null,
                                                                          string sensitiveVariablesPassword = null,
                                                                          IEnumerable <string> extensions   = null)
        {
            var variablesFile = Path.GetTempFileName();
            var variables     = new CalamariVariables();

            variables.Set(ScriptVariables.ScriptFileName, scriptName);
            variables.Set(ScriptVariables.ScriptBody, File.ReadAllText(GetFixtureResource("Scripts", scriptName)));
            variables.Set(ScriptVariables.Syntax, scriptName.ToScriptType().ToString());

            additionalVariables?.ToList().ForEach(v => variables[v.Key] = v.Value);

            using (new TemporaryFile(variablesFile))
            {
                var cmdBase = Calamari()
                              .Action("run-script");

                if (sensitiveVariablesPassword == null)
                {
                    variables.Save(variablesFile);
                    cmdBase = cmdBase.Argument("variables", variablesFile);
                }
                else
                {
                    variables.SaveEncrypted(sensitiveVariablesPassword, variablesFile);
                    cmdBase = cmdBase.Argument("sensitiveVariables", variablesFile)
                              .Argument("sensitiveVariablesPassword", sensitiveVariablesPassword);
                }

                if (extensions != null)
                {
                    cmdBase.Argument("extensions", string.Join(",", extensions));
                }

                cmdBase = (additionalParameters ?? new Dictionary <string, string>()).Aggregate(cmdBase, (cmd, param) => cmd.Argument(param.Key, param.Value));

                var output = Invoke(cmdBase, variables);

                return(output, variables);
            }
        }