private Dish process(String transition, boolean await) {
        requireNonNull(transition, "transition is null");
        int l = transition.length();
        if (l == 0) {
            throw new IllegalArgumentException("transition is the empty string (\"\")");
        }
        Parser parser = new Parser(transition);

        String fromState = parser.nextAlphaNumeric();

        int part = -1;
        int total = -1;
        parser.consume('-');
        if (parser.ifNextConsume('[')) {
            int i = parser.nextNumeric();
            if (parser.ifNextConsume('/')) {
                part = i;
                total = parser.nextNumeric();
            } else {
                total = i;
            }
            parser.consume(']');
        }
        parser.consume('>');

        String toState = parser.nextAlphaNumeric();

        if (parser.hasNext()) {
            throw new IllegalArgumentException("Specified transition contained characters after to state, transition= " + transition);
        } else if (toState != null && toState.equals(fromState)) {
            throw new IllegalArgumentException("from-state and to-state cannot be identical, transition = " + transition);
        }

        if (await) {
            Thread t = Thread.currentThread();
            try {
                inner.awaitState(t, fromState, timeoutNS);
            } catch (InterruptedException e) {
                throw new AssertionError("Interrupted while waiting", e);
            }
        }
        inner.process(Thread.currentThread(), transition, 0, fromState, toState, part, total);
        return this;

    }