class BackgroundCallable implements Callable<T> {

    @Override
    public T call() {
        if(log.isDebugEnabled()) {
            log.debug(String.format("Running background action %s", action));
        }
        final ActionOperationBatcher autorelease = ActionOperationBatcherFactory.get();
        if(action.isCanceled()) {
            // Canceled action yields no result
            return null;
        }
        if(log.isDebugEnabled()) {
            log.debug(String.format("Prepare background action %s", action));
        }
        action.prepare();
        try {
            final T result = this.run();
            if(log.isDebugEnabled()) {
                log.debug(String.format("Return result %s from background action %s", result, action));
            }
            return result;
        }
        finally {
            action.finish();
            if(log.isDebugEnabled()) {
                log.debug(String.format("Invoke cleanup for background action %s", action));
            }
            // Invoke the cleanup on the main thread to let the action synchronize the user interface
            controller.invoke(new ControllerMainAction(controller) {
                @Override
                public void run() {
                    try {
                        action.cleanup();
                    }
                    catch(Exception e) {
                        log.error(String.format("Exception %s running cleanup task", e), e);
                    }
                }
            });
            if(log.isDebugEnabled()) {
                log.debug(String.format("Releasing lock for background runnable %s", action));
            }
            autorelease.operate();
        }
    }

    public  BackgroundCallable(final BackgroundAction<T> action, final Controller controller);

}