/// <summary>
        /// This Translate signature is what the others call into - it doesn't try to hide the fact that externalDependencies should be a NonNullImmutableList
        /// of strings and it requires an ILogInformation implementation to deal with logging warnings
        /// </summary>
        public static NonNullImmutableList <TranslatedStatement> Translate(
            string scriptContent,
            NonNullImmutableList <string> externalDependencies,
            OuterScopeBlockTranslator.OutputTypeOptions outputType,
            ILogInformation logger)
        {
            if (scriptContent == null)
            {
                throw new ArgumentNullException("scriptContent");
            }
            if (externalDependencies == null)
            {
                throw new ArgumentNullException("externalDependencies");
            }
            if ((outputType != OuterScopeBlockTranslator.OutputTypeOptions.Executable) && (outputType != OuterScopeBlockTranslator.OutputTypeOptions.WithoutScaffolding))
            {
                throw new ArgumentOutOfRangeException("outputType");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            var startNamespace  = new CSharpName("TranslatedProgram");
            var startClassName  = new CSharpName("Runner");
            var startMethodName = new CSharpName("Go");
            var runtimeDateLiteralValidatorClassName = new CSharpName("RuntimeDateLiteralValidator");
            var supportRefName = new CSharpName("_");
            var envClassName   = new CSharpName("EnvironmentReferences");
            var envRefName     = new CSharpName("_env");
            var outerClassName = new CSharpName("GlobalReferences");
            var outerRefName   = new CSharpName("_outer");
            VBScriptNameRewriter nameRewriter        = name => new CSharpName(DefaultRuntimeSupportClassFactory.DefaultNameRewriter(name.Content));
            var tempNameGeneratorNextNumber          = 0;
            TempValueNameGenerator tempNameGenerator = (optionalPrefix, scopeAccessInformation) =>
            {
                // To get unique names for any given translation, a running counter is maintained and appended to the end of the generated
                // name. This is only run during translation (this code is not used during execution) so there will be a finite number of
                // times that this is called (so there should be no need to worry about the int value overflowing!)
                return(new CSharpName(((optionalPrefix == null) ? "temp" : optionalPrefix.Name) + (++tempNameGeneratorNextNumber).ToString()));
            };
            var statementTranslator = new StatementTranslator(supportRefName, envRefName, outerRefName, nameRewriter, tempNameGenerator, logger);
            var codeBlockTranslator = new OuterScopeBlockTranslator(
                startNamespace,
                startClassName,
                startMethodName,
                runtimeDateLiteralValidatorClassName,
                supportRefName,
                envClassName,
                envRefName,
                outerClassName,
                outerRefName,
                nameRewriter,
                tempNameGenerator,
                statementTranslator,
                new ValueSettingStatementsTranslator(supportRefName, envRefName, outerRefName, nameRewriter, statementTranslator, logger),
                externalDependencies.Select(name => new NameToken(name, 0)).ToNonNullImmutableList(),
                outputType,
                logger
                );

            return(codeBlockTranslator.Translate(
                       Parse(scriptContent).ToNonNullImmutableList()
                       ));
        }