// Path: core/src/main/java/se/tfiskgul/mux2fs/Constants.java
// public static final int MUX_WAIT_LOOP_MS = 500;
// 
// Path: core/src/main/java/se/tfiskgul/mux2fs/Constants.java
// public static final int SUCCESS = 0;
// 
// Path: core/src/main/java/se/tfiskgul/mux2fs/fs/base/Sleeper.java
// @FunctionalInterface
// public interface Sleeper {
// 
// 	void sleep(int millis)
// 			throws InterruptedException;
// }


import static se.tfiskgul.mux2fs.Constants.MUX_WAIT_LOOP_MS;
import static se.tfiskgul.mux2fs.Constants.SUCCESS;
import static se.tfiskgul.mux2fs.mux.Muxer.State.FAILED;
import static se.tfiskgul.mux2fs.mux.Muxer.State.NOT_STARTED;
import static se.tfiskgul.mux2fs.mux.Muxer.State.RUNNING;
import static se.tfiskgul.mux2fs.mux.Muxer.State.SUCCESSFUL;
import java.io.File;
import java.io.IOException;
import java.nio.file.AccessMode;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import se.tfiskgul.mux2fs.fs.base.Sleeper;
				access(mkv, AccessMode.READ);
				access(srt, AccessMode.READ);
				access(tempDir, AccessMode.WRITE);
				output.toFile().deleteOnExit();
				ProcessBuilder builder = factory.from("mkvmerge", "-o", output.toString(), mkv.toString(), srt.toString());
				builder.directory(tempDir.toFile()).inheritIO(); // TODO: Better solution than inheritIO
				process = builder.start();
			} catch (Exception e) {
				state.set(FAILED);
				deleteWarn(output);
				throw e;
			}
		}
	}

	private void deleteWarn(Path path) {
		if (!path.toFile().delete()) {
			logger.warn("Failed to delete {}", path);
		}
	}

	private void access(Path path, AccessMode mode)
			throws IOException {
		path.getFileSystem().provider().checkAccess(path, mode);
	}

	public State state() {
		State current = state.get();
		if (current == RUNNING) {
			if (process != null && !process.isAlive()) { // NOPMD
// Path: core/src/main/java/se/tfiskgul/mux2fs/Constants.java
// public static final int MUX_WAIT_LOOP_MS = 500;
// 
// Path: core/src/main/java/se/tfiskgul/mux2fs/Constants.java
// public static final int SUCCESS = 0;
// 
// Path: core/src/main/java/se/tfiskgul/mux2fs/fs/base/Sleeper.java
// @FunctionalInterface
// public interface Sleeper {
// 
// 	void sleep(int millis)
// 			throws InterruptedException;
// }


// Path: core/src/main/java/se/tfiskgul/mux2fs/mux/Muxer.java
import static se.tfiskgul.mux2fs.Constants.MUX_WAIT_LOOP_MS;
import static se.tfiskgul.mux2fs.Constants.SUCCESS;
import static se.tfiskgul.mux2fs.mux.Muxer.State.FAILED;
import static se.tfiskgul.mux2fs.mux.Muxer.State.NOT_STARTED;
import static se.tfiskgul.mux2fs.mux.Muxer.State.RUNNING;
import static se.tfiskgul.mux2fs.mux.Muxer.State.SUCCESSFUL;
import java.io.File;
import java.io.IOException;
import java.nio.file.AccessMode;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import se.tfiskgul.mux2fs.fs.base.Sleeper;

				access(mkv, AccessMode.READ);
				access(srt, AccessMode.READ);
				access(tempDir, AccessMode.WRITE);
				output.toFile().deleteOnExit();
				ProcessBuilder builder = factory.from("mkvmerge", "-o", output.toString(), mkv.toString(), srt.toString());
				builder.directory(tempDir.toFile()).inheritIO(); // TODO: Better solution than inheritIO
				process = builder.start();
			} catch (Exception e) {
				state.set(FAILED);
				deleteWarn(output);
				throw e;
			}
		}
	}

	private void deleteWarn(Path path) {
		if (!path.toFile().delete()) {
			logger.warn("Failed to delete {}", path);
		}
	}

	private void access(Path path, AccessMode mode)
			throws IOException {
		path.getFileSystem().provider().checkAccess(path, mode);
	}

	public State state() {
		State current = state.get();
		if (current == RUNNING) {
			if (process != null && !process.isAlive()) { // NOPMD
				if (process.exitValue() == SUCCESS) {