/// <summary>
        /// Queue a scan.
        /// </summary>
        public void Queue(bool userInitiated = false)
        {
            if (_state != States.Idle)
            {
                TSLog.LogWarning(LogCategory.Trace, "Cannot queue scan - state is not idle");
                return;
            }

            TSLog.Log(LogCategory.Trace, string.Format("Scan Queued (userInitiated={0})", userInitiated));

            _userInitiated = userInitiated;
            _state         = States.ScanQueued;
        }
        /// <summary>
        /// Checks that the current Unity version matches the version this assembly was compiled for. Will print a warning if
        /// mismatch.
        /// </summary>
        /// <returns>True if matches, otherwise false.</returns>
        public static bool EnsureCorrectUnityVersion()
        {
            var unityVersion = Application.unityVersion;

            if (unityVersion.StartsWith("4.") || unityVersion.StartsWith("5.") &&
                !(unityVersion.StartsWith("5.4.") || unityVersion.StartsWith("5.5.") ||
                  unityVersion.StartsWith("5.6.") || unityVersion.StartsWith("5.7.")))
            {
                TSLog.LogWarning(LogCategory.Info,
                                 string.Format(Strings.Warning_VersionMismatch));
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Remove all generated files from the Unity project directory
        /// </summary>
        public static void Clean()
        {
            TSLog.Log(LogCategory.Trace, "Cleaning Deploy Directory");

            var directory = PathUtility.GetDeployDirectory();

            TSLog.Log(LogCategory.Trace, "Deploy Directory: " + directory);

            foreach (var file in Directory.GetFiles(directory, "*.Generated.*"))
            {
                if (file.EndsWith(".meta"))
                {
                    continue;
                }

                var path = PathUtility.PathRelativeTo(file, Environment.CurrentDirectory);

                TSLog.Log(LogCategory.Trace, string.Format("Deleting {0}", file));

                try
                {
                    if (!FileContains(path, Strings.TypeSafeInternalTagFieldName))
                    {
                        TSLog.LogWarning(LogCategory.Trace, "File does not contain TypeSafe tag, skipped deletion.");
                        continue;
                    }

                    if (!AssetDatabase.DeleteAsset(path))
                    {
                        TSLog.LogError(LogCategory.Info,
                                       string.Format("Error deleting {0} with AssetDatabase. Attempting File.Delete", path));
                        File.Delete(path);
                    }
                }
                catch (Exception e)
                {
                    TSLog.LogError(LogCategory.Info, string.Format("Error deleting {0}", path));
                    TSLog.LogError(LogCategory.Info, e.ToString());
                }
            }
        }
        static SRProgressBar()
        {
            var t = typeof(EditorUtility).Assembly.GetType("UnityEditor.AsyncProgressBar");

            if (t != null)
            {
                _displayMethod = t.GetMethod("Display", BindingFlags.Static | BindingFlags.Public, null,
                                             new[] { typeof(string), typeof(float) }, null);

                _clearMethod = t.GetMethod("Clear", BindingFlags.Static | BindingFlags.Public, null, new Type[0], null);
            }

            if (_displayMethod == null || _clearMethod == null)
            {
                TSLog.LogWarning(LogCategory.Trace, string.Format("[TypeSafe] Error finding AsyncProgressBar ({0})", t));
                _asyncSupported = false;
            }
            else
            {
                _asyncSupported = true;
            }
        }
        private static bool CompileToDll(CodeDomProvider provider, IEnumerable <CodeCompileUnit> compileUnits,
                                         CompileParameters p, out string path)
        {
            TSLog.Log(LogCategory.Trace, "Compiling to DLL");

            var compilerParameters = new CompilerParameters();

            compilerParameters.ReferencedAssemblies.Add(typeof(int).Assembly.Location);
            compilerParameters.ReferencedAssemblies.Add(typeof(Object).Assembly.Location);
            compilerParameters.ReferencedAssemblies.Add("TypeSafe.dll");

            if (p.ResourceDatabase != null)
            {
                // Include references to assemblies used in resources

                var list = GetReferencedAssemblies(p.ResourceDatabase);

                foreach (var s in list)
                {
                    if (!compilerParameters.ReferencedAssemblies.Contains(s))
                    {
                        compilerParameters.ReferencedAssemblies.Add(s);
                    }
                }
            }

            for (var i = 0; i < compilerParameters.ReferencedAssemblies.Count; i++)
            {
                TSLog.Log(LogCategory.Trace,
                          string.Format("Referencing Assembly: {0}", compilerParameters.ReferencedAssemblies[i]));
            }

            PathUtility.EnsureDirectoryExists(PathUtility.GetBuildTempDirectory());
            compilerParameters.OutputAssembly = PathUtility.GetBuildTempDirectory() + "/" + Strings.DllName;
            //compilerParameters.TempFiles.KeepFiles = true;

            TSLog.Log(LogCategory.Trace, "Compile starting...");

            var result = provider.CompileAssemblyFromDom(compilerParameters, compileUnits.ToArray());

            if (p.LogErrors)
            {
                for (var i = 0; i < result.Errors.Count; i++)
                {
                    var error = result.Errors[i];

                    if (error.IsWarning)
                    {
                        TSLog.LogWarning(LogCategory.Compile, error.ToString());
                    }
                    else
                    {
                        TSLog.LogError(LogCategory.Compile, error.ToString());
                    }
                }
            }

            path = result.PathToAssembly;

            return(result.NativeCompilerReturnValue == 0);
        }