public Object fillBackingObject(Object incomingModel, Map request, Map session, Map application)
      throws Exception {
    // coming from matrix cell, not helper
    session.remove(WizardPageHelper.WIZARD_PAGE);

    CellFormBean cellBean = (CellFormBean) incomingModel;

    String strId = (String) request.get("page_id");
    if (strId == null) {
      strId = (String) session.get("page_id");
      session.remove("page_id");
    }

    Cell cell;
    Id id = getIdManager().getId(strId);

    // Check if the cell has been removed, which can happen if:
    // (1) user views matrix
    // (2) owner removes column or row (the code verifies that no one has
    // modified the matrix)
    // (3) user selects a cell that has just been removed with the column or
    // row
    try {
      cell = matrixManager.getCellFromPage(id);

      cellBean.setCell(cell);

      List nodeList = new ArrayList(matrixManager.getPageContents(cell.getWizardPage()));
      cellBean.setNodes(nodeList);

      if (request.get("view_user") != null) {
        session.put("view_user", cell.getWizardPage().getOwner().getId().getValue());
      }
    } catch (Exception e) {
      logger.error("Error with cell: " + strId + " " + e.toString());
      // tbd how to report error back to user?
    }

    clearSession(getSessionManager().getCurrentToolSession());
    return cellBean;
  }
  /** * Return list of AssignmentSubmissions, associated with this cell * for the current user */
  protected List getUserAssignments(CellFormBean cell) {
    ArrayList submissions = new ArrayList();
    try {
      Agent owner = cell.getCell().getWizardPage().getOwner();
      User user = UserDirectoryService.getUser(owner.getId().getValue());
      ArrayList assignments =
          AssignmentHelper.getSelectedAssignments(
              cell.getCell().getWizardPage().getPageDefinition().getAttachments());

      for (Iterator it = assignments.iterator(); it.hasNext(); ) {
        Assignment assign = (Assignment) it.next();
        AssignmentSubmission assignSubmission =
            AssignmentService.getSubmission(assign.getId(), user);
        if (assignSubmission != null) submissions.add(assignSubmission);
      }
    } catch (Exception e) {
      logger.warn(".getUserAssignments: " + e.toString());
    }

    return submissions;
  }
  public ModelAndView handleRequest(
      Object requestModel, Map request, Map session, Map application, Errors errors) {
    CellFormBean cellBean = (CellFormBean) requestModel;
    Cell cell = cellBean.getCell();

    // Check for cell being deleted while user was attempting to view
    if (cell == null) {
      return new ModelAndView("matrixError");
    }

    // String action = (String)request.get("action");
    String submit = (String) request.get("submit");
    String matrixAction = (String) request.get("matrix");
    String submitAction = (String) request.get("submitAction");
    String inviteFeedback = (String) request.get("inviteFeedback");
    String submitForReview = (String) request.get("submitForReview");

    if (inviteFeedback != null) {
      session.put("feedbackCellId", cell.getId().getValue());
      session.put("feedbackMatrixCall", "feedbackMatrixCall");

      return new ModelAndView("feedbackHelper");
    }
    if (submitForReview != null) {
      Map map = new HashMap();
      map.put("page_id", cell.getWizardPage().getId());
      map.put("feedbackCellId", cell.getId().getValue());
      map.put("cellBean", cellBean);
      return new ModelAndView("inviteFeedbackConfirm", map);
    }

    if ("tagItem".equals(submitAction)) {
      return tagItem(cell, request, session);
    } else if ("sortList".equals(submitAction)) {
      return sortList(request, session);
    } else if ("pageList".equals(submitAction)) {
      return pageList(request, session);
    }

    if (submit != null) {
      Map map = new HashMap();
      map.put("page_id", cell.getWizardPage().getId());
      map.put("selectedArtifacts", ListToString(cellBean.getSelectedArtifacts()));
      map.put("cellBean", cellBean);
      // cwm change this to use the reflection submission confirmation
      return new ModelAndView("confirm", map);
    }

    if (matrixAction != null) {
      Map map = new HashMap();
      String scaffId = "";
      String viewUser = "";
      if (getTaggingManager().isTaggable()) {
        session.remove(HibernateMatrixManagerImpl.PROVIDERS_PARAM);
      }

      if (cell.getMatrix() != null) {
        scaffId = cell.getMatrix().getScaffolding().getId().getValue();
        viewUser = cell.getMatrix().getOwner().getId().getValue();
      }

      map.put("scaffolding_id", scaffId);
      map.put("view_user", viewUser);

      if (session.get("is_eval_page_id") != null) {
        String eval_page_id = (String) session.get("is_eval_page_id");
        String pageId = cell.getWizardPage().getId().getValue();
        if (eval_page_id.equals(pageId)) {
          return new ModelAndView("cancelEvaluation");
        }
      }

      return new ModelAndView("cancel", map);
    }

    return new ModelAndView("success", "cellBean", cellBean);
  }
  public Map referenceData(Map request, Object command, Errors errors) {

    Map model = new HashMap();
    model.put("feedbackSent", false);
    ToolSession session = getSessionManager().getCurrentToolSession();

    CellFormBean cell = (CellFormBean) command;
    if (cell == null || cell.getCell() == null) {
      logger.error("Cell backing bean or cell.getCell() is null");
      clearSession(session);
      model.put("nullCellError", true);
      return model;
    }

    if (request.get("feedbackReturn") != null) {
      // feedbackReturn is returned from FeedbackHelperController and is the Id of the wizardPage of
      // the cell.
      cell.setCell(
          matrixManager.getCellFromPage(idManager.getId(request.get("feedbackReturn").toString())));
      if (request.get("feedbackAction") != null
          && request.get("feedbackAction").toString().equals("save")) {
        model.put("feedbackSent", true);
      }
    }

    model.put("matrixCanViewCell", false);
    if (request.get("comingFromWizard") == null) {
      // depending on isDefaultFeedbackEval, either send the scaffolding id or the scaffolding
      // cell's id
      boolean matrixCanEvaluate =
          getMatrixManager()
              .hasPermission(
                  cell.getCell().getScaffoldingCell().isDefaultEvaluators()
                      ? cell.getCell().getScaffoldingCell().getScaffolding().getId()
                      : cell.getCell().getScaffoldingCell().getWizardPageDefinition().getId(),
                  cell.getCell().getScaffoldingCell().getScaffolding().getWorksiteId(),
                  MatrixFunctionConstants.EVALUATE_MATRIX);
      model.put("matrixCanEvaluate", matrixCanEvaluate);
      // depending on isDefaultFeedbackEval, either send the scaffolding id or the scaffolding
      // cell's id
      // also, compare first result with the user's cell review list by sending the user's cell id
      boolean allowParticipantFeedback =
          cell.getCell().getScaffoldingCell().isDefaultReviewers()
              ? cell.getCell().getScaffoldingCell().getScaffolding().isAllowRequestFeedback()
              : cell.getCell()
                  .getScaffoldingCell()
                  .getWizardPageDefinition()
                  .isAllowRequestFeedback();
      boolean matrixCanReview =
          getMatrixManager()
                  .hasPermission(
                      cell.getCell().getScaffoldingCell().isDefaultReviewers()
                          ? cell.getCell().getScaffoldingCell().getScaffolding().getId()
                          : cell.getCell().getScaffoldingCell().getWizardPageDefinition().getId(),
                      cell.getCell().getScaffoldingCell().getScaffolding().getWorksiteId(),
                      MatrixFunctionConstants.REVIEW_MATRIX)
              || (allowParticipantFeedback
                  && getMatrixManager()
                      .hasPermission(
                          cell.getCell().getWizardPage().getId(),
                          cell.getCell().getScaffoldingCell().getScaffolding().getWorksiteId(),
                          MatrixFunctionConstants.FEEDBACK_MATRIX));
      model.put("matrixCanReview", matrixCanReview);

      boolean hasAnyReviewers =
          cell.getCell().getScaffoldingCell().isDefaultReviewers()
              ? !getMatrixManager()
                  .getSelectedUsers(
                      cell.getCell().getScaffoldingCell().getScaffolding(),
                      MatrixFunctionConstants.REVIEW_MATRIX)
                  .isEmpty()
              : !getMatrixManager()
                  .getSelectedUsers(
                      cell.getCell().getScaffoldingCell().getWizardPageDefinition(),
                      MatrixFunctionConstants.REVIEW_MATRIX)
                  .isEmpty();
      model.put("hasAnyReviewers", hasAnyReviewers);

      // NOTE: matrixCanEval or Review both return true if the user is a
      // super user:
      if (getMatrixManager().canAccessMatrixCell(cell.getCell())) {
        model.put("matrixCanViewCell", true);
      }
    } else {
      WizardPage currentWizPage =
          getMatrixManager().getWizardPage(cell.getCell().getWizardPage().getId());
      Id wizPageDefId = currentWizPage.getPageDefinition().getId();
      String wizardId =
          getWizardManager()
              .getWizardPageSeqByDef(wizPageDefId)
              .getCategory()
              .getWizard()
              .getId()
              .getValue();
      model.put("wizardId", wizardId);
      model.put(
          "isWizardOwner",
          getSessionManager()
              .getCurrentSessionUserId()
              .equals(currentWizPage.getOwner().getId().getValue()));
    }

    if (request.get("decPageId") != null
        && request.get("decWrapperTag") != null
        && request.get("decSiteId") != null) {
      // make sure that we are not coming from another wizard page which should grant you access to
      // this page
      String pageId = (String) request.get("decPageId");
      String siteId = (String) request.get("decSiteId");

      if (getMatrixManager()
          .canUserAccessWizardPageAndLinkedArtifcact(
              siteId,
              pageId,
              "/wizard/page/" + cell.getCell().getWizardPage().getId().getValue())) {
        model.put("matrixCanViewCell", true);
      }
    }

    model.put("isMatrix", "true");
    model.put("isWizard", "false");
    model.put("enableReviewEdit", getEnableReviewEdit());
    model.put("currentUser", getSessionManager().getCurrentSessionUserId());
    model.put("CURRENT_GUIDANCE_ID_KEY", "session." + GuidanceManager.CURRENT_GUIDANCE_ID);

    model.put("isEvaluation", "false");

    // This is the tool session so evaluation tool gets "is_eval_page_id"
    // and the matrix/wizard does not
    if (session.getAttribute("is_eval_page_id") != null) {
      String eval_page_id = (String) session.getAttribute("is_eval_page_id");
      model.put("isEvaluation", "true");
    }

    model.put("pageTitleKey", "view_cell");

    // Check for cell being deleted while user was attempting to view
    if (cell.getCell() == null) {
      clearSession(session);
      return model;
    }

    String pageId = cell.getCell().getWizardPage().getId().getValue();
    String siteId = cell.getCell().getWizardPage().getPageDefinition().getSiteId();
    model.put("siteId", idManager.getId(siteId));
    List reviews =
        getReviewManager()
            .getReviewsByParentAndType(pageId, Review.FEEDBACK_TYPE, siteId, getEntityProducer());
    ArrayList<Node> cellForms =
        new ArrayList<Node>(getMatrixManager().getPageForms(cell.getCell().getWizardPage()));
    Collections.sort(cellForms, new NodeNameComparator());

    if (cell.getCell().getScaffoldingCell().getWizardPageDefinition().isDefaultCustomForm()
        && request.get("comingFromWizard") == null) {
      model.put(
          "cellFormDefs",
          processAdditionalForms(
              cell.getCell().getScaffoldingCell().getScaffolding().getAdditionalForms()));
    } else {
      model.put(
          "cellFormDefs",
          processAdditionalForms(cell.getCell().getScaffoldingCell().getAdditionalForms()));
    }

    model.put("assignments", getUserAssignments(cell));
    model.put("reviews", reviews); // feedback
    model.put(
        "evaluations",
        getReviewManager()
            .getReviewsByParentAndType(
                pageId, Review.EVALUATION_TYPE, siteId, getEntityProducer()));
    model.put(
        "reflections",
        getReviewManager()
            .getReviewsByParentAndType(
                pageId, Review.REFLECTION_TYPE, siteId, getEntityProducer()));
    model.put("cellForms", cellForms);
    model.put("numCellForms", cellForms.size());

    Boolean readOnly = Boolean.valueOf(false);

    // Matrix-only initializations
    if (cell.getCell().getMatrix() != null) {
      model.put(
          "allowItemFeedback",
          getAllowItemFeedback(
              cell.getCell().getScaffoldingCell().getScaffolding().getItemFeedbackOption(),
              reviews,
              cellForms,
              cell.getNodes()));
      model.put(
          "allowGeneralFeedback",
          getAllowGeneralFeedback(
              cell.getCell().getScaffoldingCell().getScaffolding().getGeneralFeedbackOption(),
              reviews));
      model.put(
          "generalFeedbackNone",
          cell.getCell().getScaffoldingCell().getScaffolding().isGeneralFeedbackNone());

      Agent owner = cell.getCell().getMatrix().getOwner();
      readOnly =
          isReadOnly(
              owner,
              getIdManager().getId(cell.getCell().getMatrix().getScaffolding().getReference()));

      Cell pageCell = getMatrixManager().getCellFromPage(getIdManager().getId(pageId));
      Scaffolding scaffolding = pageCell.getMatrix().getScaffolding();

      model.put("objectId", scaffolding.getId().getValue());
      model.put("objectTitle", scaffolding.getTitle());
      model.put("objectDesc", scaffolding.getDescription());
      model.put(
          "wizardOwner",
          rb.getFormattedMessage("matrix_of", new Object[] {owner.getDisplayName()}));
    }

    model.put("readOnlyMatrix", readOnly);

    model.put(
        "styles",
        getStyleManager()
            .createStyleUrlList(getStyleManager().getStyles(getIdManager().getId(pageId))));

    if (getTaggingManager().isTaggable()) {
      TaggableItem item = wizardActivityProducer.getItem(cell.getCell().getWizardPage());
      model.put("taggable", "true");

      // getMatrixManager().getTaggableItems will put the providers into the session
      Set<DecoratedTaggableItem> decoTaggableItems =
          getMatrixManager()
              .getDecoratedTaggableItems(
                  item,
                  cell.getCell().getWizardPage().getPageDefinition().getReference(),
                  cell.getCell().getWizardPage().getOwner().getId().getValue());
      List<DecoratedTaggableItem> decoTaggableItemList =
          new ArrayList<DecoratedTaggableItem>(decoTaggableItems);

      Collections.sort(decoTaggableItemList, decoTaggableItemComparator);
      model.put("taggableItems", decoTaggableItemList);

      ToolSession toolSession = getSessionManager().getCurrentToolSession();
      List<DecoratedTaggingProvider> providers =
          (List) toolSession.getAttribute(HibernateMatrixManagerImpl.PROVIDERS_PARAM);
      // but just double check to make sure that providers doesn't exist
      if (providers == null) {
        providers = getMatrixManager().getDecoratedProviders(item.getActivity());
        toolSession.setAttribute(HibernateMatrixManagerImpl.PROVIDERS_PARAM, providers);
      }
      model.put("helperInfoList", getHelperInfo(item));
      model.put("providers", providers);
      model.put("criteriaRef", cell.getCell().getWizardPage().getPageDefinition().getReference());

      model.put("decoWrapper", "ospMatrix_" + siteId + "_" + pageId);
    }

    clearSession(session);
    return model;
  }