@Override
  public WorkflowInstanceLink deleteWorkflowInstanceLink(WorkflowInstanceLink workflowInstanceLink)
      throws PortalException {

    if (workflowInstanceLink == null) {
      return null;
    }

    super.deleteWorkflowInstanceLink(workflowInstanceLink);

    WorkflowInstanceManagerUtil.deleteWorkflowInstance(
        workflowInstanceLink.getCompanyId(), workflowInstanceLink.getWorkflowInstanceId());

    return workflowInstanceLink;
  }
  @Override
  public void updateClassPK(
      long companyId, long groupId, String className, long oldClassPK, long newClassPK)
      throws PortalException {

    if (!WorkflowThreadLocal.isEnabled()) {
      return;
    }

    List<WorkflowInstanceLink> workflowInstanceLinks =
        getWorkflowInstanceLinks(companyId, groupId, className, oldClassPK);

    for (WorkflowInstanceLink workflowInstanceLink : workflowInstanceLinks) {

      WorkflowInstance workflowInstance =
          WorkflowInstanceManagerUtil.getWorkflowInstance(
              workflowInstanceLink.getCompanyId(), workflowInstanceLink.getWorkflowInstanceId());

      workflowInstanceLink.setClassPK(newClassPK);

      workflowInstanceLinkPersistence.update(workflowInstanceLink);

      Map<String, Serializable> workflowContext =
          new HashMap<>(workflowInstance.getWorkflowContext());

      workflowContext.put(WorkflowConstants.CONTEXT_ENTRY_CLASS_PK, String.valueOf(newClassPK));

      WorkflowInstanceManagerUtil.updateWorkflowContext(
          workflowInstanceLink.getCompanyId(),
          workflowInstanceLink.getWorkflowInstanceId(),
          workflowContext);
    }
  }
  protected void deleteInstance(ActionRequest actionRequest) throws Exception {

    ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);

    long workflowInstanceId = ParamUtil.getLong(actionRequest, "workflowInstanceId");

    WorkflowInstance workflowInstance =
        WorkflowInstanceManagerUtil.getWorkflowInstance(
            themeDisplay.getCompanyId(), workflowInstanceId);

    Map<String, Serializable> workflowContext = workflowInstance.getWorkflowContext();

    long companyId = GetterUtil.getLong(workflowContext.get(WorkflowConstants.CONTEXT_COMPANY_ID));
    long groupId = GetterUtil.getLong(workflowContext.get(WorkflowConstants.CONTEXT_GROUP_ID));
    String className =
        GetterUtil.getString(workflowContext.get(WorkflowConstants.CONTEXT_ENTRY_CLASS_NAME));
    long classPK =
        GetterUtil.getLong(workflowContext.get(WorkflowConstants.CONTEXT_ENTRY_CLASS_PK));

    WorkflowHandler workflowHandler = WorkflowHandlerRegistryUtil.getWorkflowHandler(className);

    workflowHandler.updateStatus(WorkflowConstants.STATUS_DRAFT, workflowContext);

    WorkflowInstanceLinkLocalServiceUtil.deleteWorkflowInstanceLink(
        companyId, groupId, className, classPK);
  }
  @Override
  public void startWorkflowInstance(
      long companyId,
      long groupId,
      long userId,
      String className,
      long classPK,
      Map<String, Serializable> workflowContext)
      throws PortalException {

    if (!WorkflowThreadLocal.isEnabled()) {
      return;
    }

    if (userId == 0) {
      userId = userLocalService.getDefaultUserId(companyId);
    }

    WorkflowHandler<?> workflowHandler = WorkflowHandlerRegistryUtil.getWorkflowHandler(className);

    WorkflowDefinitionLink workflowDefinitionLink =
        workflowHandler.getWorkflowDefinitionLink(companyId, groupId, classPK);

    String workflowDefinitionName = workflowDefinitionLink.getWorkflowDefinitionName();
    int workflowDefinitionVersion = workflowDefinitionLink.getWorkflowDefinitionVersion();

    if (workflowContext != null) {
      workflowContext = new HashMap<>(workflowContext);
    } else {
      workflowContext = new HashMap<>();
    }

    workflowContext.put(WorkflowConstants.CONTEXT_COMPANY_ID, String.valueOf(companyId));
    workflowContext.put(WorkflowConstants.CONTEXT_GROUP_ID, String.valueOf(groupId));
    workflowContext.put(WorkflowConstants.CONTEXT_ENTRY_CLASS_NAME, className);
    workflowContext.put(WorkflowConstants.CONTEXT_ENTRY_CLASS_PK, String.valueOf(classPK));
    workflowContext.put(
        WorkflowConstants.CONTEXT_ENTRY_TYPE, workflowHandler.getType(LocaleUtil.getDefault()));

    WorkflowInstance workflowInstance =
        WorkflowInstanceManagerUtil.startWorkflowInstance(
            companyId,
            groupId,
            userId,
            workflowDefinitionName,
            workflowDefinitionVersion,
            null,
            workflowContext);

    addWorkflowInstanceLink(
        userId, companyId, groupId, className, classPK, workflowInstance.getWorkflowInstanceId());
  }
  @Override
  protected boolean hasPermissionImplicitlyGranted(
      PermissionChecker permissionChecker, Group group, Portlet portlet) throws Exception {

    if (WorkflowInstanceManagerUtil.getWorkflowInstanceCount(
            permissionChecker.getCompanyId(), permissionChecker.getUserId(), null, null, null)
        > 0) {

      return true;
    }

    return super.hasPermissionImplicitlyGranted(permissionChecker, group, portlet);
  }
  @Override
  public String getState(long companyId, long groupId, String className, long classPK)
      throws PortalException {

    WorkflowInstanceLink workflowInstanceLink =
        getWorkflowInstanceLink(companyId, groupId, className, classPK);

    WorkflowInstance workflowInstance =
        WorkflowInstanceManagerUtil.getWorkflowInstance(
            companyId, workflowInstanceLink.getWorkflowInstanceId());

    return workflowInstance.getState();
  }
  protected void signalInstance(ActionRequest actionRequest) throws Exception {

    ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);

    long workflowInstanceId = ParamUtil.getLong(actionRequest, "workflowInstanceId");

    String transitionName = ParamUtil.getString(actionRequest, "transitionName");

    WorkflowInstanceManagerUtil.signalWorkflowInstance(
        themeDisplay.getCompanyId(),
        themeDisplay.getUserId(),
        workflowInstanceId,
        transitionName,
        null);
  }
  @Override
  public boolean isEnded(long companyId, long groupId, String className, long classPK)
      throws PortalException {

    WorkflowInstanceLink workflowInstanceLink =
        fetchWorkflowInstanceLink(companyId, groupId, className, classPK);

    if (workflowInstanceLink == null) {
      return false;
    }

    WorkflowInstance workflowInstance =
        WorkflowInstanceManagerUtil.getWorkflowInstance(
            companyId, workflowInstanceLink.getWorkflowInstanceId());

    if (workflowInstance.getEndDate() != null) {
      return true;
    }

    return false;
  }