/// <summary>
        /// Strong Contruction
        /// </summary>
        /// <param name="map">Map to solve</param>
        public SolverController(SokobanMap map)
        {
            if (map == null) throw new ArgumentNullException("map");
            this.settings = new Settings();

            this.state = States.NotStarted;
            this.map = map;
            debugReport = new SolverReport();

            debugReport.AppendHeading(1, "SokoSolve | Solver Debug Report v{0}", ProgramVersion.VersionString);

            debugReport.Append("Creating Statistics");
            stats = new SolverStats(this);
            debugReport.Append("Creating Exit Conditions");
            exitConditions = new ItteratorExitConditions();

            // TODO: This should be configured, perhaps via a factory pattern
            debugReport.Append("Creating Forward Strategy");
            strategy = new SolverStrategy(this);
            debugReport.Append("Creating Forward Evaluator");
            evaluator = new Evaluator<SolverNode>(true);

            debugReport.Append("Creating Reverse Strategy");
            reverseStrategy = new ReverseStrategy(this);
            debugReport.Append("Creating Reverse Evaluator");
            reverseEvaluator = new Evaluator<SolverNode>(true);
        }
        /// <summary>
        /// Strong Contruction
        /// </summary>
        /// <param name="puzzleMap"></param>
        public SolverController(PuzzleMap puzzleMap)
        {
            this.puzzleMap = puzzleMap;
            debugReport = new SolverReport();
            attempted = false;
            stats = new SolverStats(this);
            exitConditions = new ExitConditions();

            // TODO: This should be configured, perhaps via a factory pattern
            strategy = new SolverStrategy(this);
            evaluator = new Evaluator<SolverNode>(true);
        }
        ///<summary>
        ///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        ///</summary>
        ///<filterpriority>2</filterpriority>
        public void Dispose()
        {
            if (reverseWorker != null)
            {
                if (reverseWorker.IsAlive) reverseWorker.Join(100);
                reverseWorker = null;
            }

            if (strategy != null)
            {
                strategy.Dispose();
                strategy = null;
            }
            if (evaluator != null)
            {
                evaluator.Dispose();
                evaluator = null;
            }
            if (reverseEvaluator != null)
            {
                reverseEvaluator.Dispose();
                reverseEvaluator = null;
            }
            if (reverseStrategy != null)
            {
                reverseStrategy.Dispose();
                reverseStrategy = null;
            }
            if (stats != null)
            {
                stats.Clear();
                stats.Dispose();
                stats = null;
            }
        }