class StreamTask extends AbstractInvokable implements AsyncExceptionHandler {

	@Override
	public final void invoke() throws Exception {
		try {
			beforeInvoke();

			// final check to exit early before starting to run
			if (canceled) {
				throw new CancelTaskException();
			}

			// let the task do its work
			runMailboxLoop();

			// if this left the run() method cleanly despite the fact that this was canceled,
			// make sure the "clean shutdown" is not attempted
			if (canceled) {
				throw new CancelTaskException();
			}

			afterInvoke();
		}
		catch (Throwable invokeException) {
			failing = !canceled;
			try {
				cleanUpInvoke();
			}
			// TODO: investigate why Throwable instead of Exception is used here.
			catch (Throwable cleanUpException) {
				Throwable throwable = ExceptionUtils.firstOrSuppressed(cleanUpException, invokeException);
				ExceptionUtils.rethrowException(throwable);
			}
			ExceptionUtils.rethrowException(invokeException);
		}
		cleanUpInvoke();
	}

	protected  StreamTask(Environment env);
	protected  StreamTask(Environment env, @Nullable TimerService timerService);
	protected  StreamTask(
			Environment environment,
			@Nullable TimerService timerService,
			Thread.UncaughtExceptionHandler uncaughtExceptionHandler);
	protected  StreamTask(
			Environment environment,
			@Nullable TimerService timerService,
			Thread.UncaughtExceptionHandler uncaughtExceptionHandler,
			StreamTaskActionExecutor actionExecutor);
	protected  StreamTask(
			Environment environment,
			@Nullable TimerService timerService,
			Thread.UncaughtExceptionHandler uncaughtExceptionHandler,
			StreamTaskActionExecutor actionExecutor,
			TaskMailbox mailbox);

}