// Path: core/src/main/java/org/mini2Dx/miniscript/core/exception/ScriptSkippedException.java
// public class ScriptSkippedException extends RuntimeException {
// 	private static final long serialVersionUID = -7901574884568506426L;
// 
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptBeginNotification.java
// public class ScriptBeginNotification implements ScriptNotification {
// 	private final AtomicBoolean processed = new AtomicBoolean(false);
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 
// 	public ScriptBeginNotification(ScriptInvocationListener invocationListener, int scriptId) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 	}
// 	@Override
// 	public void process() {
// 		invocationListener.onScriptBegin(scriptId);
// 		processed.set(true);
// 
// 		synchronized(this) {
// 			this.notifyAll();
// 		}
// 	}
// 
// 	public boolean isProcessed() {
// 		return processed.get();
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptExceptionNotification.java
// public class ScriptExceptionNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 	private final Exception exception;
// 	private final AtomicBoolean notified = new AtomicBoolean(false);
// 
// 	public ScriptExceptionNotification(ScriptInvocationListener invocationListener, int scriptId, Exception exception) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 		this.exception = exception;
// 	}
// 
// 	@Override
// 	public void process() {
// 		try {
// 			invocationListener.onScriptException(scriptId, exception);
// 		} finally {
// 			notified.set(true);
// 		}
// 
// 		synchronized(this) {
// 			notifyAll();
// 		}
// 	}
// 
// 	public void waitForNotification() {
// 		while(!notified.get()) {
// 			synchronized(this) {
// 				try {
// 					wait();
// 				} catch (InterruptedException e) {}
// 			}
// 		}
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptSkippedNotification.java
// public class ScriptSkippedNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 	private final AtomicBoolean notified = new AtomicBoolean(false);
// 	
// 	public ScriptSkippedNotification(ScriptInvocationListener invocationListener, int scriptId) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 	}
// 
// 	@Override
// 	public void process() {
// 		try {
// 			invocationListener.onScriptSkipped(scriptId);
// 		} finally {
// 			notified.set(true);
// 		}
// 
// 		synchronized(this) {
// 			notifyAll();
// 		}
// 	}
// 
// 	public void waitForNotification() {
// 		while(!notified.get()) {
// 			synchronized(this) {
// 				try {
// 					wait();
// 				} catch (InterruptedException e) {}
// 			}
// 		}
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptSuccessNotification.java
// public class ScriptSuccessNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 	private final ScriptExecutionResult executionResult;
// 	private final AtomicBoolean notified = new AtomicBoolean(false);
// 
// 	public ScriptSuccessNotification(ScriptInvocationListener invocationListener, int scriptId,
// 			ScriptExecutionResult executionResult) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 		this.executionResult = executionResult;
// 	}
// 
// 	@Override
// 	public void process() {
// 		try {
// 			invocationListener.onScriptSuccess(scriptId, executionResult);
// 		} finally {
// 			notified.set(true);
// 		}
// 
// 		synchronized(this) {
// 			notifyAll();
// 		}
// 	}
// 
// 	public void waitForNotification() {
// 		while(!notified.get()) {
// 			synchronized(this) {
// 				try {
// 					wait();
// 				} catch (InterruptedException e) {}
// 			}
// 		}
// 	}
// }


import java.util.concurrent.atomic.AtomicBoolean;
import org.mini2Dx.miniscript.core.exception.ScriptSkippedException;
import org.mini2Dx.miniscript.core.notification.ScriptBeginNotification;
import org.mini2Dx.miniscript.core.notification.ScriptExceptionNotification;
import org.mini2Dx.miniscript.core.notification.ScriptSkippedNotification;
import org.mini2Dx.miniscript.core.notification.ScriptSuccessNotification;
import java.util.concurrent.Future;
		this.executor = executor;
		this.scriptId = scriptId;
		this.script = script;
		this.scriptBindings = scriptBindings;
		this.scriptInvocationListener = scriptInvocationListener;
		this.syncCall = syncCall;
	}

	@Override
	public void run() {
		try {
			if(scriptInvocationListener != null) {
				if(scriptInvocationListener instanceof InteractiveScriptListener) {
					final ScriptInvocationListener actualListener = ((InteractiveScriptListener) scriptInvocationListener).getInvocationListener();
					invokeOnScriptBegin(actualListener);
				} else {
					invokeOnScriptBegin(scriptInvocationListener);
				}
			}

			ScriptExecutionResult executionResult = executor.execute(scriptId, script, scriptBindings,
					scriptInvocationListener != null);
			if (scriptInvocationListener != null) {
				if (scriptInvocationListener.callOnGameThread()) {
					scriptingEngine.scriptNotifications.offer(
							new ScriptSuccessNotification(scriptInvocationListener, script.getId(), executionResult));
				} else {
					scriptInvocationListener.onScriptSuccess(script.getId(), executionResult);
				}
			}
// Path: core/src/main/java/org/mini2Dx/miniscript/core/exception/ScriptSkippedException.java
// public class ScriptSkippedException extends RuntimeException {
// 	private static final long serialVersionUID = -7901574884568506426L;
// 
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptBeginNotification.java
// public class ScriptBeginNotification implements ScriptNotification {
// 	private final AtomicBoolean processed = new AtomicBoolean(false);
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 
// 	public ScriptBeginNotification(ScriptInvocationListener invocationListener, int scriptId) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 	}
// 	@Override
// 	public void process() {
// 		invocationListener.onScriptBegin(scriptId);
// 		processed.set(true);
// 
// 		synchronized(this) {
// 			this.notifyAll();
// 		}
// 	}
// 
// 	public boolean isProcessed() {
// 		return processed.get();
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptExceptionNotification.java
// public class ScriptExceptionNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 	private final Exception exception;
// 	private final AtomicBoolean notified = new AtomicBoolean(false);
// 
// 	public ScriptExceptionNotification(ScriptInvocationListener invocationListener, int scriptId, Exception exception) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 		this.exception = exception;
// 	}
// 
// 	@Override
// 	public void process() {
// 		try {
// 			invocationListener.onScriptException(scriptId, exception);
// 		} finally {
// 			notified.set(true);
// 		}
// 
// 		synchronized(this) {
// 			notifyAll();
// 		}
// 	}
// 
// 	public void waitForNotification() {
// 		while(!notified.get()) {
// 			synchronized(this) {
// 				try {
// 					wait();
// 				} catch (InterruptedException e) {}
// 			}
// 		}
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptSkippedNotification.java
// public class ScriptSkippedNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 	private final AtomicBoolean notified = new AtomicBoolean(false);
// 	
// 	public ScriptSkippedNotification(ScriptInvocationListener invocationListener, int scriptId) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 	}
// 
// 	@Override
// 	public void process() {
// 		try {
// 			invocationListener.onScriptSkipped(scriptId);
// 		} finally {
// 			notified.set(true);
// 		}
// 
// 		synchronized(this) {
// 			notifyAll();
// 		}
// 	}
// 
// 	public void waitForNotification() {
// 		while(!notified.get()) {
// 			synchronized(this) {
// 				try {
// 					wait();
// 				} catch (InterruptedException e) {}
// 			}
// 		}
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptSuccessNotification.java
// public class ScriptSuccessNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 	private final ScriptExecutionResult executionResult;
// 	private final AtomicBoolean notified = new AtomicBoolean(false);
// 
// 	public ScriptSuccessNotification(ScriptInvocationListener invocationListener, int scriptId,
// 			ScriptExecutionResult executionResult) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 		this.executionResult = executionResult;
// 	}
// 
// 	@Override
// 	public void process() {
// 		try {
// 			invocationListener.onScriptSuccess(scriptId, executionResult);
// 		} finally {
// 			notified.set(true);
// 		}
// 
// 		synchronized(this) {
// 			notifyAll();
// 		}
// 	}
// 
// 	public void waitForNotification() {
// 		while(!notified.get()) {
// 			synchronized(this) {
// 				try {
// 					wait();
// 				} catch (InterruptedException e) {}
// 			}
// 		}
// 	}
// }


// Path: core/src/main/java/org/mini2Dx/miniscript/core/ScriptExecutionTask.java
import java.util.concurrent.atomic.AtomicBoolean;
import org.mini2Dx.miniscript.core.exception.ScriptSkippedException;
import org.mini2Dx.miniscript.core.notification.ScriptBeginNotification;
import org.mini2Dx.miniscript.core.notification.ScriptExceptionNotification;
import org.mini2Dx.miniscript.core.notification.ScriptSkippedNotification;
import org.mini2Dx.miniscript.core.notification.ScriptSuccessNotification;
import java.util.concurrent.Future;

		this.executor = executor;
		this.scriptId = scriptId;
		this.script = script;
		this.scriptBindings = scriptBindings;
		this.scriptInvocationListener = scriptInvocationListener;
		this.syncCall = syncCall;
	}

	@Override
	public void run() {
		try {
			if(scriptInvocationListener != null) {
				if(scriptInvocationListener instanceof InteractiveScriptListener) {
					final ScriptInvocationListener actualListener = ((InteractiveScriptListener) scriptInvocationListener).getInvocationListener();
					invokeOnScriptBegin(actualListener);
				} else {
					invokeOnScriptBegin(scriptInvocationListener);
				}
			}

			ScriptExecutionResult executionResult = executor.execute(scriptId, script, scriptBindings,
					scriptInvocationListener != null);
			if (scriptInvocationListener != null) {
				if (scriptInvocationListener.callOnGameThread()) {
					scriptingEngine.scriptNotifications.offer(
							new ScriptSuccessNotification(scriptInvocationListener, script.getId(), executionResult));
				} else {
					scriptInvocationListener.onScriptSuccess(script.getId(), executionResult);
				}
			}
		} catch (InterruptedException | ScriptSkippedException e) {