public Map<String, FieldMetaBean> build() {
    // Get all the fields for the given project and issue type
    final Map<String, FieldMetaBean> fields = new HashMap<String, FieldMetaBean>();

    if (hasPermissionToPerformOperation()) {
      for (final FieldScreenRenderTab fieldScreenRenderTab :
          getFieldScreenRenderer(user, issue).getFieldScreenRenderTabs()) {
        for (final FieldScreenRenderLayoutItem fieldScreenRenderLayoutItem :
            fieldScreenRenderTab.getFieldScreenRenderLayoutItemsForProcessing()) {
          FieldLayoutItem fieldLayoutItem = fieldScreenRenderLayoutItem.getFieldLayoutItem();
          final OrderableField field = fieldLayoutItem.getOrderableField();
          if (field.isShown(issue)) {
            String id = field.getId();
            if (includeFields == null || includeFields.included(field)) {
              FieldMetaBean fieldMetaBean =
                  getFieldMetaBean(fieldLayoutItem.isRequired(), field, false);
              fields.put(id, fieldMetaBean);
            }
          }
        }
      }
      addAdditionalFields(fields);
    }
    return fields;
  }
  public ErrorCollection validate() {
    validateComment();

    if (errorCollection.hasAnyErrors()) return errorCollection;

    for (FieldScreenRenderTab fieldScreenRenderTab :
        getFieldScreenRenderer().getFieldScreenRenderTabs()) {
      for (FieldScreenRenderLayoutItem fieldScreenRenderLayoutItem :
          fieldScreenRenderTab.getFieldScreenRenderLayoutItemsForProcessing()) {
        if (fieldScreenRenderLayoutItem.isShow(getIssue())) {
          OrderableField orderableField = fieldScreenRenderLayoutItem.getOrderableField();

          // JRA-16112 - This is a hack that is here because the resolution field is "special". You
          // can not
          // make the resolution field required and therefore by default the FieldLayoutItem for
          // resolution
          // returns false for the isRequired method. This is so that you can not make the
          // resolution field
          // required for issue creation. HOWEVER, whenever the resolution system field is shown it
          // is
          // required because the edit template does not provide a none option and indicates that it
          // is
          // required. THEREFORE, when the field is included on a transition screen we will do a
          // special
          // check to make the FieldLayoutItem claim it is required IF we run into the resolution
          // field.
          if (IssueFieldConstants.RESOLUTION.equals(orderableField.getId())) {
            fieldScreenRenderLayoutItem =
                new FieldScreenRenderLayoutItemImpl(
                    fieldScreenRenderLayoutItem.getFieldScreenLayoutItem(),
                    fieldScreenRenderLayoutItem.getFieldLayoutItem()) {
                  public boolean isRequired() {
                    return true;
                  }
                };
          }
          orderableField.validateParams(
              getOperationContext(),
              errorCollection,
              authenticationContext.getI18nHelper(),
              getIssue(),
              fieldScreenRenderLayoutItem);
        }
      }
    }

    return errorCollection;
  }
  public ErrorCollection progress() {
    // Only update issue if transition has a screen
    if (hasScreen()) {
      for (FieldScreenRenderTab fieldScreenRenderTab :
          getFieldScreenRenderer().getFieldScreenRenderTabs()) {
        for (FieldScreenRenderLayoutItem fieldScreenRenderLayoutItem :
            fieldScreenRenderTab.getFieldScreenRenderLayoutItemsForProcessing()) {
          if (fieldScreenRenderLayoutItem.isShow(getIssue())) {
            fieldScreenRenderLayoutItem
                .getOrderableField()
                .updateIssue(fieldScreenRenderLayoutItem.getFieldLayoutItem(), getIssue(), params);
          }
        }
      }
    }

    workflowManager.doWorkflowAction(this);

    return errorCollection;
  }