private void AbortScan()
        {
            if (_state != States.Scanning)
            {
                throw new InvalidOperationException();
            }

            TSLog.Log(LogCategory.Trace, "Aborting Scan");

            _scanController = null;

            _state = States.Idle;
            TSLog.EndBuffer(LogCategory.Compile, false);
        }
        private void BeginScan()
        {
            if (_state != States.Idle && _state != States.ScanQueued)
            {
                throw new InvalidOperationException();
            }

            TSLog.BeginBuffer(LogCategory.Compile);
            TSLog.Log(LogCategory.Trace, "BeginScan");
            TypeSafeUtil.CheckForRemovedAssets();

            _stopwatch.Reset();
            _stopwatch.Start();

            _scanController = new ScanController();
            _scanController.Begin();

            _state = States.Scanning;
        }
        private void Step()
        {
            switch (State)
            {
            case States.Idle:
                break;

            case States.ScanQueued:

                if (!TypeSafeUtil.ShouldBeOperating())
                {
                    break;
                }

                BeginScan();

                break;

            case States.Scanning:

                if (_scanController == null)
                {
                    TSLog.LogError(LogCategory.Trace, "ScanController = null, but State = Scanning");
                    _state = States.Idle;
                    break;
                }

                if (!TypeSafeUtil.ShouldBeOperating())
                {
                    TSLog.Log(LogCategory.Trace, "Aborting scan due to script reload in progress.");

                    Cancel();
                    Queue();
                    break;
                }

                _scanController.Update();

                ItemsCompleted = _scanController.ItemsCompleted;
                TotalItems     = _scanController.TotalItems;

                if (_scanController.IsDone)
                {
                    TSLog.Log(LogCategory.Trace, string.Format("Scan complete (took {0}s).", _stopwatch.Elapsed.TotalSeconds));

                    if (_scanController.WasSuccessful)
                    {
                        _scanResult     = _scanController.Result;
                        _scanController = null;
                        BeginCompile();
                    }
                    else
                    {
                        TSLog.LogError(LogCategory.Info, "Error occured while scanning. Aborting process.");
                        _state = States.Idle;
                    }
                }

                break;

            case States.Compiling:
            case States.Waiting:

                if (_compileController == null)
                {
                    TSLog.LogError(LogCategory.Trace, "CompileController = null, but State = Compiling");
                    _state = States.Idle;
                    break;
                }

                if (!TypeSafeUtil.ShouldBeOperating())
                {
                    TSLog.Log(LogCategory.Trace, "Aborting compile.");
                    Cancel();
                    Queue();
                    break;
                }

                if (_compileController.IsDone)
                {
                    if (_state != States.Waiting)
                    {
                        // Perform a dry run of the deploy step to see if there were any changes since the last compile
                        int changeCount;
                        TypeSafeUtil.DeployBuildArtifacts(_compileController.Output, out changeCount, true);

                        // Delay for minimum build time if not user initiated and there were changes
                        if (Settings.Instance.EnableWaiting && changeCount > 0 && !_userInitiated &&
                            _stopwatch.Elapsed.TotalSeconds < Settings.Instance.MinimumBuildTime)
                        {
                            _state = States.Waiting;
                            break;
                        }
                    }
                    else
                    {
                        // Wait for wait stage to elapse
                        if (!_abortWait && _stopwatch.Elapsed.TotalSeconds < Settings.Instance.MinimumBuildTime)
                        {
                            break;
                        }
                    }

                    _abortWait = false;

                    TSLog.Log(LogCategory.Trace,
                              string.Format("Compile Complete (WasSuccessful={0})", _compileController.WasSuccessful));

                    if (_compileController.WasSuccessful)
                    {
                        int updatedFileCount;
                        var deployResult = TypeSafeUtil.DeployBuildArtifacts(_compileController.Output,
                                                                             out updatedFileCount);

                        TSLog.Log(LogCategory.Trace,
                                  string.Format("Deploy Complete (WasSuccessful={0}, updatedFileCount={1})", deployResult, updatedFileCount));

                        var shouldReport = _userInitiated || updatedFileCount > 0;

                        TSLog.EndBuffer(LogCategory.Compile, shouldReport);

                        if (!deployResult)
                        {
                            TSLog.LogError(LogCategory.Info, "Compile failed.");
                        }
                        else if (shouldReport)
                        {
                            if (updatedFileCount == 0)
                            {
                                TSLog.Log(LogCategory.Info, "Compile complete, no changes.");
                            }
                            else
                            {
                                TSLog.Log(LogCategory.Info,
                                          string.Format("Compile completed. (Took {0}s)", _stopwatch.Elapsed.Seconds));
                            }
                        }
                    }

                    _compileController = null;
                    _state             = States.Idle;
                }

                break;
            }
        }