public void AutoSelectSinglePath() {
   // TODO - can we do this for FinishWFT?
   /*-CONFIG-*/ String m = "AutoSelectSinglePath - ";
   /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
     DfLogger.debug(
         this, m + "check for premature Finish Click and single path selection", null, null);
   // see if the forward paths grid was ever instantiated
   Datagrid forwardgrid = (Datagrid) getControl(ForwardWorkflowTask.NEXT_TASKS_GRID_CONTROL_NAME);
   // if not, check how many paths there would be
   if (null == forwardgrid) {
     /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
       DfLogger.debug(
           this,
           m
               + "forwardgrid is null, so Finish clicked before selecting a path, see if we can autoselect",
           null,
           null);
     try {
       /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
         DfLogger.debug(this, m + "get wf task", null, null);
       IWorkflowTask task = this.getWorkflowTask();
       /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
         DfLogger.debug(
             this, m + "get forward activities for task " + task.getActivityName(), null, null);
       IDfList forwardAct = task.getNextForwardActivities();
       /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
         DfLogger.debug(this, m + "Get count of next activities", null, null);
       int count = forwardAct.getCount();
       if (1 == count) {
         /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
           DfLogger.debug(this, m + "only one next activity, so autoselect that one", null, null);
         // fake it baby
         IDfTypedObject act = (IDfTypedObject) forwardAct.get(0);
         String actId = act.getString("r_object_id");
         /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
           DfLogger.debug(this, m + "id of next activity: " + actId, null, null);
         String cboxname = "__NEXT_TASKS_CHECKBOX_CONTROL_NAME" + actId;
         /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
           DfLogger.debug(
               this, m + "creating fake checkbox for that activity: " + cboxname, null, null);
         Checkbox cbox = (Checkbox) getControl(cboxname, Checkbox.class);
         /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
           DfLogger.debug(this, m + "selecting the cbox", null, null);
         cbox.setValue(true);
         // dangerous levels of hackitude here...
         // because the superclass has the "list of next activities" property private and immutable
         // from this class, I have to resort to this trickery
         //   page == forward forces the superclass to check for selected forward paths. if it's
         // not forward, it just assumes the list is ready (which its not, and I
         //   can't make it ready since it's frikking PRIVATE. thanks, DCTM
         /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
           DfLogger.debug(
               this,
               m
                   + "set component page to forward so that the super.onCommitChanges call works correcly",
               null,
               null);
         this.setComponentPage("forward");
       }
     } catch (DfException dfe) {
       throw new RuntimeException("Df Error in single path autoselect", dfe);
     }
   }
 }
  String performValidation() throws DfException {
    /*-CONFIG-*/ String m = "performValidation-";
    /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
      DfLogger.debug(this, m + "Check if task requires signoff", null, null);
    if (m_task.isSignOffRequired()) {
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "flipping on validation", null, null);
      setDoValidation(true);

      // need to check forwarding paths' checkboxes for: at least one checked
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(
            this, m + "checking forwarding checkbox datagrid for at-least-one-checked", null, null);
      Datagrid forwardgrid =
          (Datagrid) getControl(ForwardWorkflowTask.NEXT_TASKS_GRID_CONTROL_NAME);
      Iterator i = forwardgrid.getContainedControls();
      // this seems to be infinitely looped, <sarcasm>Nice Iterator guys</sarcasm> <shrug>then
      // again, I've seen it not infinitely looped...</shrug>
      HashSet resultset =
          new HashSet(); // for tracking what we've seen and haven't seen yet so we can tell when
      // the infinitely looping iterator has looped back around
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(
            this,
            m
                + "iterating through controls, adding them to our set of checkboxes if they are of type checkbox",
            null,
            null);
      while (i.hasNext()) {
        Control current = (Control) i.next();
        if (current instanceof DatagridRow) {
          DatagridRow row = (DatagridRow) current;
          Iterator cboxes = row.getContainedControls();
          String cboxname = "";
          while (cboxes.hasNext()) {
            Control subcurrent = (Control) cboxes.next();
            if (subcurrent instanceof Checkbox) {
              cboxname = subcurrent.getName();
              /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
                DfLogger.debug(this, m + "found cbox named " + cboxname, null, null);
              break; // break from datagridrow's infinite iterator
            }
          }
          // check if we've seen this checkbox before...
          if (resultset.contains(cboxname)) break; // break from datagrid's infinite iterator
          else {
            // we haven't, so add this to the list/set of checkboxes and keep looking for new
            // checkboxes
            resultset.add(cboxname);
            /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
              DfLogger.debug(
                  this, m + "adding cbox named to cbox search results" + cboxname, null, null);
          }
        }
      }
      // okay, now we should have a list of checkbox control names we can validate...that was
      // entirely too complicated
      // CEM: this seems to be the only place that reliably can access the forward paths grid. Do
      // auto-select for single path option sets.
      int checkedcount = 0;
      int boxcount = 0;
      Checkbox firstcbox = null;
      boolean forwardPathValidation = false;
      Iterator foundcboxesiterator = resultset.iterator();
      while (foundcboxesiterator.hasNext()) {
        String name = (String) foundcboxesiterator.next();
        /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
          DfLogger.debug(this, m + "examining checkbox: " + name, null, null);
        Checkbox cbox = (Checkbox) getControl(name);
        if (0 == boxcount) firstcbox = cbox;
        boxcount++;
        if (cbox.getValue()) {
          /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
            DfLogger.debug(this, m + "checkbox is checked: " + name, null, null);
          forwardPathValidation = true;
          /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
            DfLogger.debug(this, m + "iterating checkedcount", null, null);
          checkedcount++;
          /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
            DfLogger.debug(this, m + "checkedcount is " + checkedcount, null, null);
        }
      }
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "check for autoselect of single forward path", null, null);
      if (1 == boxcount) {
        // TODO: does this interfere with reject? --> I would guess that reject triggers a RejectWFT
        // object, not this one....
        /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
          DfLogger.debug(this, m + "autochecking the single forward path", null, null);
        if (!firstcbox.getValue()) {
          firstcbox.setValue(true);
          checkedcount++;
        }
        forwardPathValidation = true;
      }

      if (forwardPathValidation == false) {
        return "MSG_FORWARD_PATH_NOT_SELECTED";
      }

      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "get State Transition config", null, null);
      StateTransitionConfigFactory config = StateTransitionConfigFactory.getSTConfig();
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "get MRCS config task definition", null, null);
      MrcsWorkflowTask t = config.getMrcsWorkflowTask(m_mrcsapp, m_processname, m_taskname);

      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(
            this,
            m + "validating checked forward path count, # selected: " + checkedcount,
            null,
            null);
      // MJH 8-29-2006: updated workflow object to be IDfWorkflow from IDfSysobject, threw CCE in
      // 5.3
      IDfProcess workflow = (IDfProcess) getDfSession().getObject(m_task.getProcessId());
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "workflow system name: " + workflow.getObjectName(), null, null);
      if (!config.doesWorkflowTaskAllowMultiplePaths(
          m_mrcsapp, workflow.getObjectName(), m_task.getTaskName())) {
        if (checkedcount > 1) {
          /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
            DfLogger.debug(
                this, m + "more than one path selected when only one is allowed", null, null);
          return "MSG_MULTIPLE_PATHS_SELECTED_WHEN_ONLY_ONE_ALLOWED";
        }
      }

      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "get refs to signing controls", null, null);
      Text usernameCtrl = (Text) getControl(QADocFinishWFT.USERNAME_CONTROL_NAME, Text.class);
      Password passwordCtrl =
          (Password) getControl(QADocFinishWFT.PASSWORD_CONTROL_NAME, Password.class);
      DropDownList rsnListCtrl =
          (DropDownList) getControl(QADocFinishWFT.REASONSELECT_CONTROL_NAME, DropDownList.class);
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "get refs to signing controls", null, null);
      String username = usernameCtrl.getValue();
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + " -- user: "******" -- pass: "******"null" : "#########"), null, null);
      String reason = rsnListCtrl.getValue();
      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + " -- reason: " + reason, null, null);

      /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
        DfLogger.debug(this, m + "calling super.validate()", null, null);
      validate();
      if (!getIsValid()) {
        return "MSG_FORM_VALIDATION";
      }
      // if ((usrName != null) && (pswd != null) && (rsn)) {
      if ((username != null)
          && (username.trim().length() > 0)
          && (password != null)
          && (reason != null)) {
        // CEM: weird bug - if password is correct, but username is wrong, then the task completes
        // but fails when we sign -- after webtop has completed the task.
        //      - so make sure the user matches the session user!
        String loggedinusername =
            getDfSession()
                .getSessionManager()
                .getIdentity(getDfSession().getDocbaseName())
                .getUser();
        if (!loggedinusername.equals(username)) {
          /*-DEBUG-*/ if (DfLogger.isDebugEnabled(this))
            DfLogger.debug(this, m + "entered username does not match current user", null, null);
          return "MSG_USERNAME_MISMATCH";
        } else {
          // apparently we need to ensure the password is correct...
          IDfLoginInfo logininfo = new DfLoginInfo();
          logininfo.setUser(username);
          logininfo.setPassword(password);
          try {
            getDfSession().authenticate(logininfo);
          } catch (DfAuthenticationException authex) {
            // return code via exception...great design, guys
            return "MSG_BAD_PASSWORD";
          }
        }

      } else {
        return "MSG_MISSING_USER_PASS_REASON";
      }
    }
    return null;
  }