// TODO: MAYBE RETURN THINGS IN SECTIONS?
        public override async Task<IEnumerable<IRotation>> Solve(CubeConfiguration<FaceColour> configuration)
        {
            await base.Solve(configuration).ConfigureAwait(false);

            m_configuration = configuration;

            var solution = new List<IRotation>();

            var cubeRotation = await CommonActions.PositionOnBottom(m_configuration, FaceColour.White).ConfigureAwait(false);

            if (cubeRotation != null)
                solution.Add(cubeRotation);

            var innerCrossesSolver = new AllInnerCrossesSolver();
            var stepsToSolveCrosses = await innerCrossesSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveCrosses);

            var innerSquareSolver = new InnerSquareSolver();
            var stepsToSolveSquares = await innerSquareSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveSquares);

            var tredgeSolver = new UpperAndDownFaceTredgesSolver();
            var stepsToSolveTredges = await tredgeSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveTredges);

            var middleTredgeSolver = new MiddleLayerTredgeSolver();
            var stepsToSolveMiddleLayerTredges = await middleTredgeSolver.Solve(configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveMiddleLayerTredges);

            // TODO: INJECT A 3x3x3 solver in here so different ones can be used
            var threeByThreeByThreeSolver = new Size3.BeginerMethod
            {
                SkipChecks = true
            };
            var stepsToSolveReduced3X3X3 = await threeByThreeByThreeSolver.Solve(configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveReduced3X3X3);

            return solution.Condense();
        }
        // TODO: MAYBE RETURN THINGS IN SECTIONS?
        public override async Task<IEnumerable<IRotation>> Solve(CubeConfiguration<FaceColour> configuration)
        {
            await base.Solve(configuration).ConfigureAwait(false);

            m_configuration = configuration;

            var solution = new List<IRotation>();

            var cubeRotation = await CommonActions.PositionOnBottom(m_configuration, FaceColour.White).ConfigureAwait(false);

            if (cubeRotation != null)
                solution.Add(cubeRotation);

            var stepsToSolveBottomCross = await m_bottomCrossSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveBottomCross);

            var stepsToSolveBottomLayer = await m_bottomLayerSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveBottomLayer);

            var stepsToSolveMiddleLayer = await m_middleLayerSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveMiddleLayer);

            var stepsToSolveTopCross = await m_topCrossSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveTopCross);

            var stepsToSolveTopFace = await m_topFaceSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveTopFace);

            var stepsToSolveTopLayer = await m_topLayerSolver.Solve(m_configuration).ConfigureAwait(false);

            solution.AddRange(stepsToSolveTopLayer);

            return solution.Condense();
        }