@Override
  protected String finishImpl(FacesContext context, String outcome) throws Exception {
    // find out what the parent type of the node being deleted
    Node node = this.browseBean.getActionSpace();
    NodeRef parent = null;
    ChildAssociationRef assoc = this.getNodeService().getPrimaryParent(node.getNodeRef());
    if (assoc != null) {
      // get the parent node
      parent = assoc.getParentRef();

      // if the parent type is a forum space then we need the dialog to go
      // back to the forums view otherwise it will use the default of 'browse',
      // this happens when a forum being used to discuss a node is deleted.
      QName parentType = this.getNodeService().getType(parent);
      if (parentType.equals(ForumModel.TYPE_FORUMS)) {
        this.reDisplayForums = true;
      }
    }

    // delete the forum itself
    outcome = super.finishImpl(context, outcome);

    // remove the discussable aspect if appropriate
    if (assoc != null && parent != null) {
      // get the association type
      QName type = assoc.getTypeQName();
      if (type.equals(ForumModel.ASSOC_DISCUSSION)) {
        // if the association type is the 'discussion' association we
        // need to remove the discussable aspect from the parent node
        this.getNodeService().removeAspect(parent, ForumModel.ASPECT_DISCUSSABLE);
      }
    }

    return outcome;
  }
  /**
   * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
   */
  public boolean evaluate(final Node node) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    AVMService avmService = Repository.getServiceRegistry(facesContext).getAVMService();

    Pair<Integer, String> p = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef());
    AVMNodeDescriptor nodeDesc = avmService.lookup(-1, p.getSecond());

    // don't allow action if its a 'layeredfolder' and a primary indirection
    return !(nodeDesc.getType() == AVMNodeType.LAYERED_DIRECTORY && nodeDesc.isPrimary());
  }
  /**
   * Checkout document to the same space as original one and then add the OFFLINE_EDITING property.
   */
  private void checkoutFile(Node node) {
    UserTransaction tx = null;
    FacesContext context = FacesContext.getCurrentInstance();

    if (node != null) {
      try {
        tx = Repository.getUserTransaction(context, false);
        tx.begin();

        if (logger.isDebugEnabled())
          logger.debug("Trying to checkout content node Id: " + node.getId());
        NodeRef workingCopyRef = null;

        // checkout the content to the current space
        workingCopyRef = property.getVersionOperationsService().checkout(node.getNodeRef());
        getNodeService()
            .setProperty(workingCopyRef, ContentModel.PROP_WORKING_COPY_MODE, OFFLINE_EDITING);

        // set the working copy Node instance
        Node workingCopy = new Node(workingCopyRef);
        property.setWorkingDocument(workingCopy);

        // create content URL to the content download servlet with ID and
        // expected filename
        String url =
            DownloadContentServlet.generateDownloadURL(workingCopyRef, workingCopy.getName());

        workingCopy.getProperties().put("url", url);
        workingCopy
            .getProperties()
            .put("fileType32", FileTypeImageUtils.getFileTypeImage(workingCopy.getName(), false));

        // commit the transaction
        tx.commit();
      } catch (Throwable err) {
        try {
          if (tx != null) {
            tx.rollback();
          }
        } catch (Exception tex) {
        }

        Utils.addErrorMessage(
            Application.getMessage(FacesContext.getCurrentInstance(), MSG_ERROR_CHECKOUT)
                + err.getMessage(),
            err);
      }
    } else {
      logger.warn("WARNING: checkoutFile called without a current Document!");
    }
  }
  /**
   * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
   */
  public boolean evaluate(final Node node) {
    // is the authenticated user permitted to execute the regenerate renditions action
    // against at least one web project
    boolean isUserAllowed = false;

    final FacesContext fc = FacesContext.getCurrentInstance();
    final ServiceRegistry services = Repository.getServiceRegistry(fc);
    final PermissionService permissionService = services.getPermissionService();
    final WebProjectService webProjectService = services.getWebProjectService();
    final NavigationBean navigator =
        (NavigationBean) FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME);

    // check that the authenticated user has CONTENT MANAGER permissions for at least one web
    // project
    // this will ensure that the action appears only if the user is able to regenerate renditions
    // for at least one web project
    List<WebProjectInfo> wpInfos = webProjectService.listWebProjects();
    for (WebProjectInfo wpInfo : wpInfos) {
      if (permissionService.hasPermission(
              wpInfo.getNodeRef(), PermissionService.WCM_CONTENT_MANAGER)
          == AccessStatus.ALLOWED) {
        isUserAllowed = true;
        break;
      }
    }

    // TODO improve how we determine whether the form supports the ability to regenerate renditions
    // or not

    // get the path to the current name - compare each path element with the Web Forms folder name
    final Path path = navigator.getCurrentNode().getNodePath();

    boolean isWebFormsPath = false;
    Iterator<Path.Element> itr = path.iterator();
    while (itr.hasNext()) {
      Path.Element element = (Path.Element) itr.next();
      String pathElement = element.getPrefixedString(services.getNamespaceService());
      if (Application.getWebContentFormsFolderName(fc).equals(pathElement)) {
        isWebFormsPath = true;
        break;
      }
    }

    return (node.hasAspect(WCMAppModel.ASPECT_RENDERING_ENGINE_TEMPLATE) || isWebFormsPath)
        && isUserAllowed;
  }