// Path: core/src/main/java/org/mini2Dx/miniscript/core/exception/InsufficientCompilersException.java
// public class InsufficientCompilersException extends Exception {
// 	private static final long serialVersionUID = 2947579725300422095L;
// 
// 	public InsufficientCompilersException() {
// 		super("There were insufficient compilers available to compile the provided script");
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/exception/NoSuchScriptException.java
// public class NoSuchScriptException extends RuntimeException {
// 
// 	public NoSuchScriptException(int scriptId) {
// 		super("No script with id " + scriptId + " exists");
// 	}
// 
// 	public NoSuchScriptException(String filepath) {
// 		super("No script " + filepath + " exists");
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptCancelledNotification.java
// public class ScriptCancelledNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 
// 	public ScriptCancelledNotification(ScriptInvocationListener invocationListener, int scriptId) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 	}
// 
// 	@Override
// 	public void process() {
// 		invocationListener.onScriptCancelled(scriptId);
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptNotification.java
// public interface ScriptNotification {
// 
// 	public void process();
// }
// 
// 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/threadpool/DefaultThreadPoolProvider.java
// public class DefaultThreadPoolProvider implements ThreadPoolProvider {
// 	private static final String THREAD_NAME_PREFIX = "miniscript-thread-";
// 	private static final AtomicInteger THREAD_ID = new AtomicInteger(0);
// 
// 	private final ScheduledExecutorService executorService;
// 
// 	public DefaultThreadPoolProvider() {
// 		this(Runtime.getRuntime().availableProcessors() + 1);
// 	}
// 
// 	public DefaultThreadPoolProvider(int maxConcurrentScripts) {
// 		executorService = Executors.newScheduledThreadPool(
// 				Math.min(maxConcurrentScripts + 1, Runtime.getRuntime().availableProcessors() * 2),
// 				new ThreadFactory() {
// 					@Override
// 					public Thread newThread(Runnable r) {
// 						return new Thread(r, THREAD_NAME_PREFIX + THREAD_ID.getAndIncrement());
// 					}
// 				});
// 	}
// 
// 	@Override
// 	public Future<?> submit(Runnable task) {
// 		return executorService.submit(task);
// 	}
// 
// 	@Override
// 	public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
// 		return executorService.scheduleAtFixedRate(command, initialDelay, period, unit);
// 	}
// 
// 	@Override
// 	public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
// 		return executorService.schedule(command, delay, unit);
// 	}
// 
// 	@Override
// 	public void shutdown(boolean interruptThreads) {
// 		if(interruptThreads) {
// 			executorService.shutdownNow();
// 		} else {
// 			executorService.shutdown();
// 		}
// 	}
// }


import org.mini2Dx.miniscript.core.threadpool.DefaultThreadPoolProvider;
import org.mini2Dx.miniscript.core.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.mini2Dx.lockprovider.Locks;
import org.mini2Dx.lockprovider.jvm.JvmLocks;
import org.mini2Dx.miniscript.core.exception.InsufficientCompilersException;
import org.mini2Dx.miniscript.core.exception.NoSuchScriptException;
import org.mini2Dx.miniscript.core.notification.ScriptCancelledNotification;
import org.mini2Dx.miniscript.core.notification.ScriptNotification;
import org.mini2Dx.miniscript.core.notification.ScriptSkippedNotification;
			if (scriptExecutionTask.getScriptId() != scriptId) {
				continue;
			}
			scriptExecutionTask.skipScript();
		}
	}

	/**
	 * Skips a specific running instance of a script
	 *
	 * @param taskId The ID of the task to skip
	 */
	public void skipScriptByTaskId(int taskId) {
		final IntMap.Keys keys = runningScripts.keys();
		while(keys.hasNext) {
			final int otherTaskId = keys.next();
			if(taskId != otherTaskId) {
				continue;
			}
			ScriptExecutionTask<?> scriptExecutionTask = runningScripts.get(taskId);
			if (scriptExecutionTask == null) {
				continue;
			}
			scriptExecutionTask.skipScript();
		}
	}

	/**
	 * Skips all currently running {@link GameFuture}s
	 */
// Path: core/src/main/java/org/mini2Dx/miniscript/core/exception/InsufficientCompilersException.java
// public class InsufficientCompilersException extends Exception {
// 	private static final long serialVersionUID = 2947579725300422095L;
// 
// 	public InsufficientCompilersException() {
// 		super("There were insufficient compilers available to compile the provided script");
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/exception/NoSuchScriptException.java
// public class NoSuchScriptException extends RuntimeException {
// 
// 	public NoSuchScriptException(int scriptId) {
// 		super("No script with id " + scriptId + " exists");
// 	}
// 
// 	public NoSuchScriptException(String filepath) {
// 		super("No script " + filepath + " exists");
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptCancelledNotification.java
// public class ScriptCancelledNotification implements ScriptNotification {
// 	private final ScriptInvocationListener invocationListener;
// 	private final int scriptId;
// 
// 	public ScriptCancelledNotification(ScriptInvocationListener invocationListener, int scriptId) {
// 		this.invocationListener = invocationListener;
// 		this.scriptId = scriptId;
// 	}
// 
// 	@Override
// 	public void process() {
// 		invocationListener.onScriptCancelled(scriptId);
// 	}
// }
// 
// Path: core/src/main/java/org/mini2Dx/miniscript/core/notification/ScriptNotification.java
// public interface ScriptNotification {
// 
// 	public void process();
// }
// 
// 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/threadpool/DefaultThreadPoolProvider.java
// public class DefaultThreadPoolProvider implements ThreadPoolProvider {
// 	private static final String THREAD_NAME_PREFIX = "miniscript-thread-";
// 	private static final AtomicInteger THREAD_ID = new AtomicInteger(0);
// 
// 	private final ScheduledExecutorService executorService;
// 
// 	public DefaultThreadPoolProvider() {
// 		this(Runtime.getRuntime().availableProcessors() + 1);
// 	}
// 
// 	public DefaultThreadPoolProvider(int maxConcurrentScripts) {
// 		executorService = Executors.newScheduledThreadPool(
// 				Math.min(maxConcurrentScripts + 1, Runtime.getRuntime().availableProcessors() * 2),
// 				new ThreadFactory() {
// 					@Override
// 					public Thread newThread(Runnable r) {
// 						return new Thread(r, THREAD_NAME_PREFIX + THREAD_ID.getAndIncrement());
// 					}
// 				});
// 	}
// 
// 	@Override
// 	public Future<?> submit(Runnable task) {
// 		return executorService.submit(task);
// 	}
// 
// 	@Override
// 	public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
// 		return executorService.scheduleAtFixedRate(command, initialDelay, period, unit);
// 	}
// 
// 	@Override
// 	public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
// 		return executorService.schedule(command, delay, unit);
// 	}
// 
// 	@Override
// 	public void shutdown(boolean interruptThreads) {
// 		if(interruptThreads) {
// 			executorService.shutdownNow();
// 		} else {
// 			executorService.shutdown();
// 		}
// 	}
// }


// Path: core/src/main/java/org/mini2Dx/miniscript/core/GameScriptingEngine.java
import org.mini2Dx.miniscript.core.threadpool.DefaultThreadPoolProvider;
import org.mini2Dx.miniscript.core.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.mini2Dx.lockprovider.Locks;
import org.mini2Dx.lockprovider.jvm.JvmLocks;
import org.mini2Dx.miniscript.core.exception.InsufficientCompilersException;
import org.mini2Dx.miniscript.core.exception.NoSuchScriptException;
import org.mini2Dx.miniscript.core.notification.ScriptCancelledNotification;
import org.mini2Dx.miniscript.core.notification.ScriptNotification;
import org.mini2Dx.miniscript.core.notification.ScriptSkippedNotification;

			if (scriptExecutionTask.getScriptId() != scriptId) {
				continue;
			}
			scriptExecutionTask.skipScript();
		}
	}

	/**
	 * Skips a specific running instance of a script
	 *
	 * @param taskId The ID of the task to skip
	 */
	public void skipScriptByTaskId(int taskId) {
		final IntMap.Keys keys = runningScripts.keys();
		while(keys.hasNext) {
			final int otherTaskId = keys.next();
			if(taskId != otherTaskId) {
				continue;
			}
			ScriptExecutionTask<?> scriptExecutionTask = runningScripts.get(taskId);
			if (scriptExecutionTask == null) {
				continue;
			}
			scriptExecutionTask.skipScript();
		}
	}

	/**
	 * Skips all currently running {@link GameFuture}s
	 */
	public void skipAllRunningGameFutures() {