def UpdateHuntOutputPluginState(self,
                                  hunt_id,
                                  state_index,
                                  update_fn,
                                  cursor=None):
    """Updates hunt output plugin state for a given output plugin."""

    hunt_id_int = db_utils.HuntIDToInt(hunt_id)

    query = "SELECT hunt_id FROM hunts WHERE hunt_id = %s"
    rows_returned = cursor.execute(query, [hunt_id_int])
    if rows_returned == 0:
      raise db.UnknownHuntError(hunt_id)

    columns = ", ".join(_HUNT_OUTPUT_PLUGINS_STATES_COLUMNS)
    query = ("SELECT {columns} FROM hunt_output_plugins_states "
             "WHERE hunt_id = %s AND plugin_id = %s".format(columns=columns))
    rows_returned = cursor.execute(query, [hunt_id_int, state_index])
    if rows_returned == 0:
      raise db.UnknownHuntOutputPluginStateError(hunt_id, state_index)

    state = self._HuntOutputPluginStateFromRow(cursor.fetchone())
    modified_plugin_state = update_fn(state.plugin_state)

    query = ("UPDATE hunt_output_plugins_states "
             "SET plugin_state = %s "
             "WHERE hunt_id = %s AND plugin_id = %s")
    args = [modified_plugin_state.SerializeToString(), hunt_id_int, state_index]
    cursor.execute(query, args)
    return state