protected void changeTutorial(Parameters params, Map sitemapParams) throws ProcessingException {
    final String METHOD_NAME = "changeTutorial";
    this.getLogger().debug(METHOD_NAME + " 1/2: Started");

    DbHelper dbHelper = null;
    try {
      // Init services:
      dbHelper = (DbHelper) this.manager.lookup(DbHelper.ROLE);

      // Get data from parameters:
      int userId = ParamUtil.getAsInt(params, "user");
      int classId = ParamUtil.getAsId(params, "class");
      int oldTutorialId = ParamUtil.getAsInt(params, "old-tutorial");
      int newTutorialId = ParamUtil.getAsInt(params, "new-tutorial");

      // Both tutorials must belong to the specified class:
      int oldTutorialClassId =
          dbHelper.getPseudoDocDatumAsInt(PseudoDocType.TUTORIAL, oldTutorialId, DbColumn.CLASS);
      int newTutorialClassId =
          dbHelper.getPseudoDocDatumAsInt(PseudoDocType.TUTORIAL, newTutorialId, DbColumn.CLASS);
      if (oldTutorialClassId != classId)
        throw new IllegalArgumentException("Old tutorial does not belong to the specified class");
      if (newTutorialClassId != classId)
        throw new IllegalArgumentException("New tutorial does not belong to the specified class");

      dbHelper.beginTransaction(this, true);

      // Remove user from old tutorial:
      dbHelper.removeTutorialMember(oldTutorialId, userId);

      // Add user to new tutorial:
      dbHelper.addTutorialMember(newTutorialId, userId);

      dbHelper.endTransaction(this);

      this.getLogger().debug(METHOD_NAME + " 2/2: Done");
    } catch (Exception exception) {
      throw new ProcessingException(exception);
    } finally {
      if (dbHelper != null)
        try {
          if (dbHelper.hasTransactionLocked(this)) dbHelper.abortTransaction(this);
        } catch (Exception exception) {
          throw new ProcessingException(exception);
        } finally {
          this.manager.release(dbHelper);
        }
    }
  }
  /** See class description. */
  public Map act(
      Redirector redirector,
      SourceResolver resolver,
      Map objectModel,
      String source,
      Parameters parameters)
      throws ProcessingException {
    final String METHOD_NAME = "act";
    this.getLogger().debug(METHOD_NAME + " 1/2: Started");

    try {
      // Init sitemap parameters to return:
      Map sitemapParams = new HashMap();

      int formStage = ParamUtil.getAsInt(parameters, "form-stage", 0);
      sitemapParams.put("form-stage", formStage);
      switch (formStage) {
        case 0:
          // Do nothing, only inform sitemap to generate form and set the user:
          int userId = ParamUtil.getAsInt(parameters, "id", -1);
          sitemapParams.put("mode", "form");
          sitemapParams.put("user", Integer.toString(userId));
          break;
        case 1:
          // Change tutorial:
          this.changeTutorial(parameters, sitemapParams);
          break;
        default:
          throw new IllegalArgumentException("Illegal form-stage value: " + formStage);
      }

      this.getLogger().debug(METHOD_NAME + " 2/2: Done");

      return sitemapParams;
    } catch (Exception exception) {
      throw new ProcessingException(exception);
    }
  }
  public Map act(
      Redirector redirector,
      SourceResolver sourceResolver,
      Map objectModel,
      String source,
      Parameters parameters)
      throws ProcessingException {
    final String METHOD_NAME = "act";
    this.getLogger().debug(METHOD_NAME + " 1/2: Started");
    UserWorksheetGradeMessage message = null;

    try {
      // Get data:
      int userId = ParamUtil.getAsId(parameters, "user");
      int worksheetId = ParamUtil.getAsId(parameters, "worksheet");
      String destinationName = ParamUtil.getAsString(parameters, "destination");

      // Setup message object:
      message = (UserWorksheetGradeMessage) this.manager.lookup(UserWorksheetGradeMessage.ROLE);
      message.setup(userId, worksheetId, destinationName);

      // Send message:
      boolean success = message.send();

      // Compose sitemap parameters:
      Map sitemapParams = new HashMap();
      sitemapParams.put("message-status", (success ? "Ok" : "Failed"));

      this.getLogger().debug(METHOD_NAME + " 2/2: Done. success = " + success);

      return sitemapParams;
    } catch (Exception exception) {
      throw new ProcessingException(exception);
    } finally {
      if (message != null) this.manager.release(message);
    }
  }