@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
	public File doValidate(File base, File script, Condition eventSynchronisation, boolean securityEnabled,
						   String securityLevel, String hostString, final int timeout) {
		FanOutStreamSender fanOutStreamSender = null;
		ErrorStreamRedirectWorkerLauncher workerLauncher = null;
		boolean stopByTooMuchExecution = false;
		ByteArrayOutputStream byteArrayErrorStream = new ByteArrayOutputStream();
		File file = new File(base, "validation-0.log");
		try {

			fanOutStreamSender = new FanOutStreamSender(1);
			deleteLogs(base);

			AbstractLanguageHandler handler = Lang.getByFileName(script).getHandler();
			AbstractGrinderClassPathProcessor classPathProcessor = handler.getClassPathProcessor();
			GrinderProperties properties = new GrinderProperties();
			PropertyBuilder builder = new ValidationPropertyBuilder(properties, new Directory(base), securityEnabled, securityLevel, hostString,
				NetworkUtils.getLocalHostName());
			properties.setInt("grinder.agents", 1);
			properties.setInt("grinder.processes", 1);
			properties.setInt("grinder.threads", 1);
			properties.setBoolean("grinder.script.validation", true);
			String grinderJVMClassPath = getHomeLibraryPath(classPathProcessor.buildForemostClasspathBasedOnCurrentClassLoader(LOGGER))
				+ File.pathSeparator + getHomeLibraryPath(classPathProcessor.buildPatchClasspathBasedOnCurrentClassLoader(LOGGER))
				+ File.pathSeparator + builder.buildCustomClassPath(true);
			properties.setProperty(GRINDER_PROP_JVM_CLASSPATH, grinderJVMClassPath = grinderJVMClassPath.replace(";;", ";"));
			LOGGER.info(GRINDER_PROP_JVM_CLASSPATH + " : {} ", grinderJVMClassPath);
			AgentIdentityImplementation agentIdentity = new AgentIdentityImplementation("validation");
			agentIdentity.setNumber(0);
			String newClassPath = classPathProcessor.buildClasspathBasedOnCurrentClassLoader(LOGGER);
			LOGGER.debug("validation class path " + newClassPath);
			Properties systemProperties = new Properties();

			String path;
			if (isRunningOnWas()) {
				path = getHomeLibraryPath(newClassPath);
			} else {
				path = runtimeClassPath() + newClassPath;
			}
			systemProperties.put("java.class.path", path);

			Directory workingDirectory = new Directory(base);
			String buildJVMArgumentWithoutMemory = builder.buildJVMArgumentWithoutMemory();
			LOGGER.info("jvm args : {} ", buildJVMArgumentWithoutMemory);
			final WorkerProcessCommandLine workerCommandLine = new WorkerProcessCommandLine(properties,
					systemProperties, buildJVMArgumentWithoutMemory, workingDirectory);

			ScriptLocation scriptLocation = new ScriptLocation(workingDirectory, script);
			ProcessWorkerFactory workerFactory = new ProcessWorkerFactory(workerCommandLine, agentIdentity,
					fanOutStreamSender, false, scriptLocation, properties);

			workerLauncher = new ErrorStreamRedirectWorkerLauncher(1, workerFactory, eventSynchronisation, LOGGER,
					byteArrayErrorStream);

			// Start
			workerLauncher.startAllWorkers();
			// Wait for a termination event.
			synchronized (eventSynchronisation) {
				final long sleep = 1000;
				int waitingCount = 0;
				while (true) {
					if (workerLauncher.allFinished()) {
						break;
					}
					if (waitingCount++ > timeout) {
						LOGGER.error("Validation should be performed within {} sec. Stop it by force", timeout);
						workerLauncher.destroyAllWorkers();
						stopByTooMuchExecution = true;
						break;
					}
					eventSynchronisation.waitNoInterrruptException(sleep);
				}
			}
		} catch (Exception e) {
			LOGGER.error("Error while executing {} because {}", script, e.getMessage());
			LOGGER.info("The error detail is ", e);
			appendingMessageOn(file, ExceptionUtils.getFullStackTrace(e));
		} finally {
			if (workerLauncher != null) {
				workerLauncher.shutdown();
			}
			if (fanOutStreamSender != null) {
				fanOutStreamSender.shutdown();
			}
			// To be safe, wait again..
			int waitingCount = 0;
			while (workerLauncher != null) {
				final int maximumWaitingCount = 10;
				if (workerLauncher.allFinished() || waitingCount++ > maximumWaitingCount) {
					break;
				}
				synchronized (eventSynchronisation) {
					eventSynchronisation.waitNoInterrruptException(1000);
				}
			}

		}
		appendingMessageOn(file, byteArrayErrorStream.toString());
		File errorValidation = new File(base, "error_validation-0.log");
		if (errorValidation.exists()) {
			String errorValidationResult = "";
			try {
				errorValidationResult = FileUtils.readFileToString(errorValidation);
			} catch (IOException e) {
				noOp();
			}
			appendingMessageOn(file, errorValidationResult);
		}
		if (stopByTooMuchExecution) {
			appendingMessageOn(file, "Validation should be performed within " + timeout + " sec. Stop it by force");
		}
		return file;
	}
Validate script.

@param base                 working directory
@param script               script file
@param eventSynchronisation condition for event synchronization
@param securityEnabled      if security is set or not.
@param hostString           hostString
@param timeout              timeout in sec.
@return File which stores validation result.
ngrinder-core/src/main/java/net/grinder/engine/agent/LocalScriptTestDriveService.java