private void RemoveState(int frame, int branch = -1)
        {
            if (branch == -1)
            {
                accessed.Remove(States[frame]);
            }
            else if (accessed.Contains(BranchStates[frame][branch]) && !Settings.EraseBranchStatesFirst)
            {
                accessed.Remove(BranchStates[frame][branch]);
            }

            StateManagerState state;
            bool hasDuplicate = stateHasDuplicate(frame, branch) != -2;

            if (branch == -1)
            {
                state = States[frame];
                if (States[frame].IsOnDisk)
                {
                    States[frame].Dispose();
                }
                else
                {
                    Used -= (ulong)States[frame].Length;
                }
                States.RemoveAt(States.IndexOfKey(frame));
            }
            else
            {
                state = BranchStates[frame][branch];
                if (BranchStates[frame][branch].IsOnDisk)
                {
                    BranchStates[frame][branch].Dispose();
                }
                else
                {
                    Used -= (ulong)BranchStates[frame][branch].Length;
                }
                BranchStates[frame].RemoveAt(BranchStates[frame].IndexOfKey(branch));

                if (BranchStates[frame].Count == 0)
                {
                    BranchStates.Remove(frame);
                }
            }

            if (!hasDuplicate)
            {
                lowPriorityStates.Remove(state);
            }
        }
        /// <summary>
        /// X is the frame of the state, Y is the branch (-1 for current).
        /// </summary>
        private Point StateToRemove()
        {
            // X is frame, Y is branch
            Point shouldRemove = new Point(-1, -1);

            if (BranchStates.Any() && Settings.EraseBranchStatesFirst)
            {
                var kvp = BranchStates.Count() > 1 ? BranchStates.ElementAt(1) : BranchStates.ElementAt(0);
                shouldRemove.X = kvp.Key;
                shouldRemove.Y = kvp.Value.Keys[0];

                return(shouldRemove);
            }

            int i           = 0;
            int markerSkips = maxStates / 2;

            // lowPrioritySates (e.g. states with only lag frames between them)
            do
            {
                if (lowPriorityStates.Count > i)
                {
                    shouldRemove = findState(lowPriorityStates[i]);
                }
                else
                {
                    break;
                }

                // Keep marker states
                markerSkips--;
                if (markerSkips < 0)
                {
                    shouldRemove.X = -1;
                }
                i++;
            } while (StateIsMarker(shouldRemove.X, shouldRemove.Y) && markerSkips > -1 || shouldRemove.X == 0);

            // by last accessed
            markerSkips = maxStates / 2;
            if (shouldRemove.X < 1)
            {
                i = 0;
                do
                {
                    if (accessed.Count > i)
                    {
                        shouldRemove = findState(accessed[i]);
                    }
                    else
                    {
                        break;
                    }

                    // Keep marker states
                    markerSkips--;
                    if (markerSkips < 0)
                    {
                        shouldRemove.X = -1;
                    }
                    i++;
                } while (StateIsMarker(shouldRemove.X, shouldRemove.Y) && markerSkips > -1 || shouldRemove.X == 0);
            }

            if (shouldRemove.X < 1)             // only found marker states above
            {
                if (BranchStates.Any() && !Settings.EraseBranchStatesFirst)
                {
                    var kvp = BranchStates.Count() > 1 ? BranchStates.ElementAt(1) : BranchStates.ElementAt(0);
                    shouldRemove.X = kvp.Key;
                    shouldRemove.Y = kvp.Value.Keys[0];
                }
                else
                {
                    StateManagerState s = States.Values[1];
                    shouldRemove.X = s.Frame;
                    shouldRemove.Y = -1;
                }
            }

            return(shouldRemove);
        }