public override int Run(TOptions options)
        {
            //  To correctly initialize the logger, we must first add Hashes to dataToInsert
#pragma warning disable CS0618 // Type or member is obsolete
            if (options.ComputeFileHashes)
#pragma warning restore CS0618
            {
                OptionallyEmittedData dataToInsert = options.DataToInsert.ToFlags();
                dataToInsert |= OptionallyEmittedData.Hashes;

                options.DataToInsert = Enum.GetValues(typeof(OptionallyEmittedData)).Cast <OptionallyEmittedData>()
                                       .Where(oed => dataToInsert.HasFlag(oed)).ToList();
            }

            // 0. Initialize an common logger that drives all outputs. This
            //    object drives logging for console, statistics, etc.
            using (AggregatingLogger logger = InitializeLogger(options))
            {
                //  Once the logger has been correctly initialized, we can raise a warning
                _rootContext = CreateContext(options, logger, RuntimeErrors);
#pragma warning disable CS0618 // Type or member is obsolete
                if (options.ComputeFileHashes)
#pragma warning restore CS0618
                {
                    Warnings.LogObsoleteOption(_rootContext, "--hashes", SdkResources.ComputeFileHashes_ReplaceInsertHashes);
                }

                try
                {
                    Analyze(options, logger);
                }
                catch (ExitApplicationException <ExitReason> ex)
                {
                    // These exceptions have already been logged
                    ExecutionException = ex;
                    return(FAILURE);
                }
                catch (Exception ex)
                {
                    // These exceptions escaped our net and must be logged here
                    RuntimeErrors     |= Errors.LogUnhandledEngineException(_rootContext, ex);
                    ExecutionException = ex;
                    return(FAILURE);
                }
                finally
                {
                    logger.AnalysisStopped(RuntimeErrors);
                }
            }

            bool succeeded = (RuntimeErrors & ~RuntimeConditions.Nonfatal) == RuntimeConditions.None;

            if (options.RichReturnCode)
            {
                return((int)RuntimeErrors);
            }

            return(succeeded ? SUCCESS : FAILURE);
        }