class BaseJavaDelegate implements JavaDelegate {

    @Override
    public final void execute(DelegateExecution execution) throws Exception
    {
        long taskBeginTimeMillis = 0;
        boolean taskSuccessFlag = false;
        try
        {
            // Set the task begin time
            taskBeginTimeMillis = System.currentTimeMillis();
            
            // Need to clear the security context here since the current thread may have been reused,
            // which may might have left over its security context. If we do not clear the security
            // context, any subsequent calls may be restricted by the permissions given
            // to the previous thread's security context.
            SecurityContextHolder.clearContext();

            // Check if method is not allowed.
            configurationDaoHelper.checkNotAllowedMethod(this.getClass().getCanonicalName());

            // Set the security context per last updater of the current process instance's job definition.
            ApplicationUser applicationUser = getApplicationUser(execution);
            setSecurityContext(applicationUser);

            // Set the MDC property for the Activiti process instance ID and user ID.
            MDC.put(ACTIVITI_PROCESS_INSTANCE_ID_KEY, "activitiProcessInstanceId=" + execution.getProcessInstanceId());
            MDC.put(USER_ID_KEY, "userId=" + (applicationUser.getUserId() == null ? "" : applicationUser.getUserId()));

            // Log all input variables from the execution (before the execution starts).
            logInputParameters(execution);

            // Perform the execution implementation handled in the sub-class.
            executeImpl(execution);

            // Set a success status as a workflow variable.
            activitiRuntimeHelper.setTaskSuccessInWorkflow(execution);

            // Set the flag to true since there is no exception thrown
            taskSuccessFlag = true;
        }
        catch (Exception ex)
        {
            handleException(execution, ex);
        }
        finally
        {
            // Log the task execution time
            logTaskExecutionTime(taskBeginTimeMillis, taskSuccessFlag);

            // Remove the MDC property to ensure they don't accidentally get used by anybody else.
            MDC.remove(ACTIVITI_PROCESS_INSTANCE_ID_KEY);
            MDC.remove(USER_ID_KEY);

            // Clear up the security context.
            SecurityContextHolder.clearContext();
        }
    }

}