@Override
  public synchronized <T> T execute(Command<T> command) {
    boolean transactionOwner = false;
    T result = null;

    try {
      transactionOwner = txm.begin();
      tpm.beginCommandScopedEntityManager();
      TransactionManagerHelper.registerTransactionSyncInContainer(
          this.txm, new TaskSynchronizationImpl(this));

      result = executeNext((Command<T>) command);
      postInit(result);
      txm.commit(transactionOwner);

      return result;

    } catch (TaskException e) {
      // allow to handle TaskException as business exceptions on caller side
      // if transaction is owned by other component like process engine
      if (transactionOwner) {
        rollbackTransaction(e, transactionOwner);
        e.setRecoverable(false);
        throw e;
      } else {
        throw e;
      }
    } catch (RuntimeException re) {
      rollbackTransaction(re, transactionOwner);
      throw re;
    } catch (Exception t1) {
      rollbackTransaction(t1, transactionOwner);
      throw new RuntimeException("Wrapped exception see cause", t1);
    }
  }
  @Override
  public Context getContext() {

    final TaskPersistenceContext persistenceContext = tpm.getPersistenceContext();
    persistenceContext.joinTransaction();

    return new TaskContext() {

      @Override
      public void set(String identifier, Object value) {
        txm.putResource(identifier, value);
      }

      @Override
      public void remove(String identifier) {}

      @Override
      public String getName() {
        return null;
      }

      @Override
      public World getContextManager() {
        return null;
      }

      @Override
      public Object get(String identifier) {
        return txm.getResource(identifier);
      }

      @Override
      public void setPersistenceContext(TaskPersistenceContext context) {}

      @Override
      public TaskPersistenceContext getPersistenceContext() {
        return persistenceContext;
      }

      @Override
      public UserGroupCallback getUserGroupCallback() {
        return null;
      }

      @Override
      public Task loadTaskVariables(Task task) {
        return task;
      }
    };
  }