Verify that the outputs that can be generated by fsm have their
    requirements satisfied by the given rich inputs.

    @param richInputs: A L{list} of all of the types which will serve as rich
        inputs to an L{IFiniteStateMachine}.
    @type richInputs: L{list} of L{IRichInput} providers

    @param fsm: The L{IFiniteStateMachine} to which these rich inputs are to be
        delivered.

    @param inputContext: A L{dict} mapping output symbols to L{Interface}
        subclasses.  Rich inputs which result in these outputs being produced
        by C{fsm} must provide the corresponding interface.

    @raise DoesNotImplement: If any of the rich input types fails to implement
        the interfaces required by the outputs C{fsm} can produce when they are
        received.

def _checkConsistency(richInputs, fsm, inputContext):
    """
    Verify that the outputs that can be generated by fsm have their
    requirements satisfied by the given rich inputs.

    @param richInputs: A L{list} of all of the types which will serve as rich
        inputs to an L{IFiniteStateMachine}.
    @type richInputs: L{list} of L{IRichInput} providers

    @param fsm: The L{IFiniteStateMachine} to which these rich inputs are to be
        delivered.

    @param inputContext: A L{dict} mapping output symbols to L{Interface}
        subclasses.  Rich inputs which result in these outputs being produced
        by C{fsm} must provide the corresponding interface.

    @raise DoesNotImplement: If any of the rich input types fails to implement
        the interfaces required by the outputs C{fsm} can produce when they are
        received.
    """
    for richInput in richInputs:
        for state in fsm:
            for input in fsm[state]:
                if richInput.symbol() == input:
                    # This rich input will be supplied to represent this input
                    # symbol in this state.  Check to see if it satisfies the
                    # output requirements.
                    outputs = fsm[state][input].output
                    for output in outputs:
                        try:
                            required = inputContext[output]
                        except KeyError:
                            continue
                        # Consider supporting non-interface based checking in
                        # the future: extend this to also allow
                        # issubclass(richInput, required)
                        if required.implementedBy(richInput):
                            continue
                        raise DoesNotImplement(
                            "%r not implemented by %r, "
                            "required by %r in state %r" % (
                                required, richInput,
                                input, state))