'Split a stash of states. The stash from_stash will be split into two stashes depending on the other options
passed in. If to_stash is provided, the second stash will be written there.
stash_splitter overrides stash_ranker, which in turn overrides state_ranker. If no functions are provided, the
states are simply split according to the limit.
The sort done with state_ranker is ascending.
:param stash_splitter:  A function that should take a list of states and return a tuple of two lists (the two
resulting stashes).
:param stash_ranker:    A function that should take a list of states and return a sorted list of states. This list
will then be split according to "limit".
:param state_ranker:        An alternative to stash_splitter. States will be sorted with outputs of this function.
used as a key. The first "limit" of them will be kept, the rest split off.
:param limit:           For use with state_ranker. The number of states to keep. Default: 8
:param from_stash:      The stash to split (default: \'active\')
:param to_stash:        The stash to write to (default: \'stashed\')
:returns:               The resulting SimulationManager.
:rtype:                 SimulationManager'

def split(self, stash_splitter=None, stash_ranker=None, state_ranker=None, limit=None, from_stash=None, to_stash=None):

    limit = (8 if (limit is None) else limit)
    from_stash = ('active' if (from_stash is None) else from_stash)
    to_stash = ('stashed' if (to_stash is None) else to_stash)
    new_stashes = self._copy_stashes()
    old_states = new_stashes[from_stash]
    if (stash_splitter is not None):
        (keep, split) = stash_splitter(old_states)
    elif (stash_ranker is not None):
        ranked_states = stash_ranker(old_states)
        (keep, split) = (ranked_states[:limit], ranked_states[limit:])
    elif (state_ranker is not None):
        ranked_states = sorted(old_states, key=state_ranker)
        (keep, split) = (ranked_states[:limit], ranked_states[limit:])
    else:
        (keep, split) = (old_states[:limit], old_states[limit:])
    new_stashes[from_stash] = keep
    new_stashes[to_stash] = (split if (to_stash not in new_stashes) else (new_stashes[to_stash] + split))
    return self._successor(new_stashes)
