// Path: src/main/java/x/mvmn/gp2srv/camera/CameraService.java
// public interface CameraService {
// 	public void close();
// 
// 	public byte[] capturePreview();
// 
// 	public CameraService releaseCamera();
// 
// 	public CameraFileSystemEntryBean capture();
// 
// 	public CameraFileSystemEntryBean capture(GP2CameraCaptureType captureType);
// 
// 	public String getSummary();
// 
// 	public GP2CameraEventType waitForSpecificEvent(int timeout, GP2CameraEventType expectedEventType);
// 
// 	public GP2CameraEventType waitForEvent(int timeout);
// 
// 	public List<CameraConfigEntryBean> getConfig();
// 
// 	public Map<String, CameraConfigEntryBean> getConfigAsMap();
// 
// 	public CameraService setConfig(CameraConfigEntryBean configEntry);
// 
// 	public List<CameraFileSystemEntryBean> filesList(final String path, boolean includeFiles, boolean includeFolders, boolean recursive);
// 
// 	public CameraService fileDelete(final String filePath, final String fileName);
// 
// 	public byte[] fileGetContents(final String filePath, final String fileName);
// 
// 	public byte[] fileGetThumb(final String filePath, final String fileName);
// 
// 	public String downloadFile(final String cameraFilePath, final String cameraFileName, final File downloadFolder);
// 
// 	public CameraProvider getCameraProvider();
// }
// 
// Path: src/main/java/x/mvmn/gp2srv/scripting/service/impl/JexlMapContext.java
// public class JexlMapContext extends MapContext {
// 
// 	protected final Map<String, Object> vars;
// 
// 	public JexlMapContext() {
// 		this(new TreeMap<String, Object>());
// 	}
// 
// 	protected JexlMapContext(Map<String, Object> vars) {
// 		super(vars);
// 		this.vars = vars;
// 	}
// 
// 	public Set<String> variableNames() {
// 		return Collections.unmodifiableSet(vars.keySet());
// 	}
// 
// 	public Map<String, Object> toMap() {
// 		return new TreeMap<String, Object>(vars);
// 	}
// }
// 
// Path: src/main/java/x/mvmn/lang/util/WaitUtil.java
// public class WaitUtil {
// 
// 	public static void ensuredWait(long totalWaitTime) {
// 		long waitTime = totalWaitTime;
// 		long startTime = System.currentTimeMillis();
// 		long projectedEndTime = startTime + totalWaitTime;
// 		do {
// 			try {
// 				if (waitTime > 0) {
// 					Thread.sleep(waitTime);
// 				}
// 			} catch (InterruptedException e) {
// 				// Wait time = Total wait time - passed time (e.g. total wait for 10 sec, interrupted after 3 sec, still 7 sec to wait)
// 				// Passed time = now - start time
// 				waitTime = totalWaitTime - (System.currentTimeMillis() - startTime);
// 			}
// 		} while (System.currentTimeMillis() < projectedEndTime);
// 	}
// }


import java.io.File;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlExpression;
import x.mvmn.gp2srv.camera.CameraService;
import x.mvmn.gp2srv.scripting.service.impl.JexlMapContext;
import x.mvmn.jlibgphoto2.api.CameraConfigEntryBean;
import x.mvmn.jlibgphoto2.api.CameraFileSystemEntryBean;
import x.mvmn.jlibgphoto2.api.GP2Camera.GP2CameraEventType;
import x.mvmn.lang.util.WaitUtil;

	protected ScriptStepType type;
	protected String key;
	protected String expression;
	protected String condition;

	protected transient volatile JexlExpression conditionExpressionCache;
	protected transient volatile JexlExpression expressionExpressionCache;

	public ScriptStep() {
	}

	public ScriptStep(ScriptStepType type, String key, String expression, String condition) {
		this.setType(type);
		this.setKey(key);
		this.setExpression(expression);
		this.setCondition(condition);
	}

	public boolean evalCondition(JexlEngine engine, JexlMapContext context) {
		boolean execute = true;
		if (condition != null && !condition.trim().isEmpty()) {
			execute = Boolean
					.valueOf((conditionExpressionCache == null ? (conditionExpressionCache = engine.createExpression(condition)) : conditionExpressionCache)
							.evaluate(context).toString());
		}

		return execute;
	}

// Path: src/main/java/x/mvmn/gp2srv/camera/CameraService.java
// public interface CameraService {
// 	public void close();
// 
// 	public byte[] capturePreview();
// 
// 	public CameraService releaseCamera();
// 
// 	public CameraFileSystemEntryBean capture();
// 
// 	public CameraFileSystemEntryBean capture(GP2CameraCaptureType captureType);
// 
// 	public String getSummary();
// 
// 	public GP2CameraEventType waitForSpecificEvent(int timeout, GP2CameraEventType expectedEventType);
// 
// 	public GP2CameraEventType waitForEvent(int timeout);
// 
// 	public List<CameraConfigEntryBean> getConfig();
// 
// 	public Map<String, CameraConfigEntryBean> getConfigAsMap();
// 
// 	public CameraService setConfig(CameraConfigEntryBean configEntry);
// 
// 	public List<CameraFileSystemEntryBean> filesList(final String path, boolean includeFiles, boolean includeFolders, boolean recursive);
// 
// 	public CameraService fileDelete(final String filePath, final String fileName);
// 
// 	public byte[] fileGetContents(final String filePath, final String fileName);
// 
// 	public byte[] fileGetThumb(final String filePath, final String fileName);
// 
// 	public String downloadFile(final String cameraFilePath, final String cameraFileName, final File downloadFolder);
// 
// 	public CameraProvider getCameraProvider();
// }
// 
// Path: src/main/java/x/mvmn/gp2srv/scripting/service/impl/JexlMapContext.java
// public class JexlMapContext extends MapContext {
// 
// 	protected final Map<String, Object> vars;
// 
// 	public JexlMapContext() {
// 		this(new TreeMap<String, Object>());
// 	}
// 
// 	protected JexlMapContext(Map<String, Object> vars) {
// 		super(vars);
// 		this.vars = vars;
// 	}
// 
// 	public Set<String> variableNames() {
// 		return Collections.unmodifiableSet(vars.keySet());
// 	}
// 
// 	public Map<String, Object> toMap() {
// 		return new TreeMap<String, Object>(vars);
// 	}
// }
// 
// Path: src/main/java/x/mvmn/lang/util/WaitUtil.java
// public class WaitUtil {
// 
// 	public static void ensuredWait(long totalWaitTime) {
// 		long waitTime = totalWaitTime;
// 		long startTime = System.currentTimeMillis();
// 		long projectedEndTime = startTime + totalWaitTime;
// 		do {
// 			try {
// 				if (waitTime > 0) {
// 					Thread.sleep(waitTime);
// 				}
// 			} catch (InterruptedException e) {
// 				// Wait time = Total wait time - passed time (e.g. total wait for 10 sec, interrupted after 3 sec, still 7 sec to wait)
// 				// Passed time = now - start time
// 				waitTime = totalWaitTime - (System.currentTimeMillis() - startTime);
// 			}
// 		} while (System.currentTimeMillis() < projectedEndTime);
// 	}
// }


// Path: src/main/java/x/mvmn/gp2srv/scripting/model/ScriptStep.java
import java.io.File;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlExpression;
import x.mvmn.gp2srv.camera.CameraService;
import x.mvmn.gp2srv.scripting.service.impl.JexlMapContext;
import x.mvmn.jlibgphoto2.api.CameraConfigEntryBean;
import x.mvmn.jlibgphoto2.api.CameraFileSystemEntryBean;
import x.mvmn.jlibgphoto2.api.GP2Camera.GP2CameraEventType;
import x.mvmn.lang.util.WaitUtil;


	protected ScriptStepType type;
	protected String key;
	protected String expression;
	protected String condition;

	protected transient volatile JexlExpression conditionExpressionCache;
	protected transient volatile JexlExpression expressionExpressionCache;

	public ScriptStep() {
	}

	public ScriptStep(ScriptStepType type, String key, String expression, String condition) {
		this.setType(type);
		this.setKey(key);
		this.setExpression(expression);
		this.setCondition(condition);
	}

	public boolean evalCondition(JexlEngine engine, JexlMapContext context) {
		boolean execute = true;
		if (condition != null && !condition.trim().isEmpty()) {
			execute = Boolean
					.valueOf((conditionExpressionCache == null ? (conditionExpressionCache = engine.createExpression(condition)) : conditionExpressionCache)
							.evaluate(context).toString());
		}

		return execute;
	}

	public CameraConfigEntryBean getConfigEntryForEval(CameraService cameraService) {