class QLExpressScriptExecutor extends ScriptExecutor {

	private final Logger log = LoggerFactory.getLogger(this.getClass());

	private ExpressRunner expressRunner;

	private final Map<String, InstructionSet> compiledScriptMap = new CopyOnWriteHashMap<>();

	@Override
	public ScriptExecutor init() {
		expressRunner = new ExpressRunner(true, false);
		return this;
	}

	@Override
	public void load(String nodeId, String script) {
		try {
			compiledScriptMap.put(nodeId, (InstructionSet) compile(script));
		}
		catch (Exception e) {
			String errorMsg = StrUtil.format("script loading error for node[{}],error msg:{}", nodeId, e.getMessage());
			throw new ScriptLoadException(errorMsg);
		}
	}

	@Override
	public void unLoad(String nodeId) {
		compiledScriptMap.remove(nodeId);
	}

	@Override
	public List<String> getNodeIds() {
		return new ArrayList<>(compiledScriptMap.keySet());
	}

	@Override
	public Object executeScript(ScriptExecuteWrap wrap) throws Exception {<FILL_FUNCTION_BODY>}

	@Override
	public void cleanCache() {
		compiledScriptMap.clear();
		expressRunner.clearExpressCache();
		ReflectUtil.setFieldValue(expressRunner, "loader", new ExpressLoader(expressRunner));
	}

	@Override
	public ScriptTypeEnum scriptType() {
		return ScriptTypeEnum.QLEXPRESS;
	}

	@Override
	public Object compile(String script) throws Exception {
		return expressRunner.getInstructionSetFromLocalCache(script);
	}

}

		List<String> errorList = new ArrayList<>();
		try {
			if (!compiledScriptMap.containsKey(wrap.getNodeId())) {
				String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId());
				throw new ScriptLoadException(errorMsg);
			}

			InstructionSet instructionSet = compiledScriptMap.get(wrap.getNodeId());
			DefaultContext<String, Object> context = new DefaultContext<>();

			bindParam(wrap, context::put, context::putIfAbsent);

			return expressRunner.execute(instructionSet, context, errorList, true, false);
		}
		catch (Exception e) {
			for (String scriptErrorMsg : errorList) {
				log.error("\n{}", scriptErrorMsg);
			}
			throw e;
		}
	
<methods>public non-sealed void <init>() ,public void bindParam(com.yomahub.liteflow.script.ScriptExecuteWrap, BiConsumer<java.lang.String,java.lang.Object>, BiConsumer<java.lang.String,java.lang.Object>) ,public abstract void cleanCache() ,public abstract java.lang.Object compile(java.lang.String) throws java.lang.Exception,public java.lang.Object execute(com.yomahub.liteflow.script.ScriptExecuteWrap) throws java.lang.Exception,public abstract java.lang.Object executeScript(com.yomahub.liteflow.script.ScriptExecuteWrap) throws java.lang.Exception,public abstract List<java.lang.String> getNodeIds() ,public com.yomahub.liteflow.script.ScriptExecutor init() ,public abstract void load(java.lang.String, java.lang.String) ,public abstract com.yomahub.liteflow.enums.ScriptTypeEnum scriptType() ,public abstract void unLoad(java.lang.String) <variables>