The code throws a lot of IllegalStateExceptions (ISE).
It also throws some IllegalArgumentExceptions (IAE).
These need reviewing to check that ISE really does apply to the current state, and IAE is used for reporting an incorrect argument.
Generally if ISE applies, no argument values will be valid.
IAE should be used when a specific argument or set of arguments is invalid.