public bool Next(int index, Tristate selected)
            {
                switch (state)
                {
                case State.Initial:
                    if (selected.IsYes())
                    {
                        state         = State.InRun;
                        runCount      = 1;
                        runStartIndex = index;
                    }
                    return(false);

                case State.JustAfterRun:
                    if (selected.IsYes())
                    {
                        state         = State.InRun;
                        runCount      = 1;
                        runStartIndex = index;
                        goto checkCases;
                    }
                    else
                    {
                        state        = State.Initial;
                        prevRunCount = 0;
                        runCount     = 0;
                    }
                    return(false);

                case State.InRun:
                    if (selected.IsYes())
                    {
                        state     = State.InRun;
                        runCount += 1;
                        if (runCount > max)
                        {
                            // Immediate contradiction
                            return(true);
                        }
                        goto checkCases;
                    }
                    else
                    {
                        // Also case 1.
                        if (runCount == max)
                        {
                            if (selected.Possible())
                            {
                                banAt(index);
                            }
                        }
                        state        = State.JustAfterRun;
                        prevRunCount = runCount;
                        runCount     = 0;
                    }
                    return(false);
                }
                // Unreachable
                throw new Exception("Unreachable");
checkCases:
                // Have we entered case 1 or 2?
                if (prevRunCount + runCount == max)
                {
                    // Ban on the previous end of the run
                    if (runStartIndex == 0)
                    {
                        if (periodic)
                        {
                            banAt(indexCount - 1);
                        }
                    }
                    else
                    {
                        banAt(runStartIndex - 1);
                    }
                }
                return(false);
            }