Read, modify, create or remove Managed Objects Instances.

        Given one or more py:class:`~pysnmp.smi.rfc1902.ObjectType`, recursively
        transitions corresponding Managed Objects Instances through the Finite State
        Machine (FSM) states till it reaches its final stop state.

        Parameters
        ----------
        fsmTable: :py:class:`dict`
            A map of (`state`, `status`) -> `state` representing FSM transition matrix.
            See :py:class:`RowStatus` for FSM transition logic.

        varBinds: :py:class:`tuple` of :py:class:`~pysnmp.smi.rfc1902.ObjectType` objects
            representing Managed Objects Instances to work with.

        Other Parameters
        ----------------
        \*\*context:

            Query parameters:

            * `cbFun` (callable) - user-supplied callable that is invoked to
                pass the new value of the Managed Object Instance or an error.

            * `acFun` (callable) - user-supplied callable that is invoked to
                authorize access to the requested Managed Object Instance. If
                not supplied, no access control will be performed.

        Notes
        -----
        The callback functions (e.g. `cbFun`, `acFun`) have the same signature
        as this method where `varBind` contains the new Managed Object Instance
        value.

        In case of errors, the `errors` key in the `context` dict will contain
        a sequence of `dict` objects describing one or more errors that occur.

        Such error `dict` will have the `error`, `idx` and `state` keys providing
        the details concerning the error, for which variable-binding and in what
        state the system has failed.

def flipFlopFsm(self, fsmTable, *varBinds, **context):
        """Read, modify, create or remove Managed Objects Instances.

        Given one or more py:class:`~pysnmp.smi.rfc1902.ObjectType`, recursively
        transitions corresponding Managed Objects Instances through the Finite State
        Machine (FSM) states till it reaches its final stop state.

        Parameters
        ----------
        fsmTable: :py:class:`dict`
            A map of (`state`, `status`) -> `state` representing FSM transition matrix.
            See :py:class:`RowStatus` for FSM transition logic.

        varBinds: :py:class:`tuple` of :py:class:`~pysnmp.smi.rfc1902.ObjectType` objects
            representing Managed Objects Instances to work with.

        Other Parameters
        ----------------
        \*\*context:

            Query parameters:

            * `cbFun` (callable) - user-supplied callable that is invoked to
                pass the new value of the Managed Object Instance or an error.

            * `acFun` (callable) - user-supplied callable that is invoked to
                authorize access to the requested Managed Object Instance. If
                not supplied, no access control will be performed.

        Notes
        -----
        The callback functions (e.g. `cbFun`, `acFun`) have the same signature
        as this method where `varBind` contains the new Managed Object Instance
        value.

        In case of errors, the `errors` key in the `context` dict will contain
        a sequence of `dict` objects describing one or more errors that occur.

        Such error `dict` will have the `error`, `idx` and `state` keys providing
        the details concerning the error, for which variable-binding and in what
        state the system has failed.
        """
        count = [0]

        cbFun = context.get('cbFun')

        def _cbFun(varBind, **context):
            idx = context.pop('idx', None)

            err = context.pop('error', None)
            if err:
                # Move other errors into the errors sequence
                errors = context['errors']

                errors.append(
                    {'error': err,
                     'idx': idx,
                     'varbind': varBind,
                     'state': context['state']})

                context['status'] = self.STATUS_ERROR

            if idx is None:
                if cbFun:
                    cbFun((), **context)
                return

            _varBinds = context['varBinds']

            _varBinds[idx] = varBind

            count[0] += 1

            debug.logger & debug.FLAG_INS and debug.logger(
                '_cbFun: var-bind %d, processed %d, expected '
                '%d' % (idx, count[0], len(varBinds)))

            if count[0] < len(varBinds):
                return

            debug.logger & debug.FLAG_INS and debug.logger(
                '_cbFun: finished, output var-binds %r' % (_varBinds,))

            self.flipFlopFsm(fsmTable, *varBinds, **dict(context, cbFun=cbFun))

        debug.logger & debug.FLAG_INS and debug.logger(
            'flipFlopFsm: input var-binds %r' % (varBinds,))

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        try:
            state = context['state']
            status = context['status']
            instances = context['instances']
            errors = context['errors']
            _varBinds = context['varBinds']

        except KeyError:
            state, status = self.STATE_START, self.STATUS_OK
            instances = {}
            errors = []
            _varBinds = list(varBinds)

            self._indexMib()

        debug.logger & debug.FLAG_INS and debug.logger(
            'flipFlopFsm: current state %s, status %s' % (state, status))

        try:
            newState = fsmTable[(state, status)]

        except KeyError:
            try:
                newState = fsmTable[(self.STATE_ANY, status)]

            except KeyError:
                raise error.SmiError(
                    'Unresolved FSM state %s, %s' % (state, status))

        debug.logger & debug.FLAG_INS and debug.logger(
            'flipFlopFsm: state %s status %s -> transitioned into state '
            '%s' % (state, status, newState))

        state = newState

        if state == self.STATE_STOP:
            context.pop('state', None)
            context.pop('status', None)
            context.pop('instances', None)
            context.pop('varBinds', None)

            if cbFun:
                cbFun(_varBinds, **context)

            return

        # the case of no var-binds
        if not varBinds:
            _cbFun(None, **context)
            return

        actionFun = getattr(mibTree, state, None)
        if not actionFun:
            raise error.SmiError(
                'Unsupported state handler %s at '
                '%s' % (state, self))

        for idx, varBind in enumerate(varBinds):
            actionFun(
                varBind,
                **dict(context, cbFun=_cbFun, state=state, status=status,
                       idx=idx, total=len(varBinds), instances=instances,
                       errors=errors, varBinds=_varBinds, nextName=None))

            debug.logger & debug.FLAG_INS and debug.logger(
                'flipFlopFsm: func %s initiated for %r' % (actionFun, varBind))