// 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;
			if (scriptInvocationListener != null) {
				if (scriptInvocationListener.callOnGameThread()) {
					scriptingEngine.scriptNotifications
							.offer(new ScriptSkippedNotification(scriptInvocationListener, script.getId()));
				} else {
					scriptInvocationListener.onScriptSkipped(script.getId());
				}
			}
		} catch (Exception e) {
			if (scriptInvocationListener != null) {
				if (scriptInvocationListener.callOnGameThread()) {
					scriptingEngine.scriptNotifications
							.offer(new ScriptExceptionNotification(scriptInvocationListener, script.getId(), e));
				} else {
					scriptInvocationListener.onScriptException(script.getId(), e);
				}
			} else {
				e.printStackTrace();
			}
		}
		// Clear interrupted bit
		Thread.interrupted();
		completed.set(true);
	}

	private void invokeOnScriptBegin(ScriptInvocationListener listener) throws InterruptedException {
		if(listener == null) {
			return;
		}
		if(listener.callOnGameThread() && !syncCall) {
// 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;

			if (scriptInvocationListener != null) {
				if (scriptInvocationListener.callOnGameThread()) {
					scriptingEngine.scriptNotifications
							.offer(new ScriptSkippedNotification(scriptInvocationListener, script.getId()));
				} else {
					scriptInvocationListener.onScriptSkipped(script.getId());
				}
			}
		} catch (Exception e) {
			if (scriptInvocationListener != null) {
				if (scriptInvocationListener.callOnGameThread()) {
					scriptingEngine.scriptNotifications
							.offer(new ScriptExceptionNotification(scriptInvocationListener, script.getId(), e));
				} else {
					scriptInvocationListener.onScriptException(script.getId(), e);
				}
			} else {
				e.printStackTrace();
			}
		}
		// Clear interrupted bit
		Thread.interrupted();
		completed.set(true);
	}

	private void invokeOnScriptBegin(ScriptInvocationListener listener) throws InterruptedException {
		if(listener == null) {
			return;
		}
		if(listener.callOnGameThread() && !syncCall) {
			final ScriptBeginNotification beginNotification = new ScriptBeginNotification(listener, scriptId);