class TimeoutGuardPipe extends FixedForwardPipe {

	@Override
	public PipeRunResult doPipe(Message message, IPipeLineSession session) throws PipeRunException {
		ParameterValueList pvl = null;
		if (getParameterList() != null) {
			try {
				pvl = getParameterList().getValues(message, session);
			} catch (ParameterException e) {
				throw new PipeRunException(this, getLogPrefix(session) + "exception on extracting parameters", e);
			}
		}
		int timeout_work;
		String timeout_work_str = getParameterValue(pvl, "timeout");
		if (timeout_work_str == null) {
			timeout_work = getTimeout();
		} else {
			timeout_work = Integer.valueOf(timeout_work_str);
		}

		log.debug(getLogPrefix(session) + "setting timeout of [" + timeout_work + "] s");
		TimeoutGuard tg = new TimeoutGuard(timeout_work, getName()) {
			@Override
			protected void kill() {
				//The guard automatically kills the current thread, additional threads maybe 'killed' by implementing killPipe.
				killPipe();
			}
		};

		try {
			return doPipeWithTimeoutGuarded(message, session);
		} catch (Exception e) {
			String msg = e.getClass().getName();

			if (isThrowException()) {
				throw new PipeRunException(this, msg, e);
			} else {
				String msgString = msg + ": " + e.getMessage();
				log.error(msgString, e);
				String msgCdataString = "<![CDATA[" + msgString + "]]>";
				Message errorMessage = new Message("<error>" + msgCdataString + "</error>");
				return new PipeRunResult(getForward(), errorMessage);
			}
		} finally {
			if(tg.cancel()) {
				//Throw a TimeOutException
				String msgString = "TimeOutException";
				Exception e = new TimeOutException("exceeds timeout of [" + timeout_work + "] s, interupting");
				if (isThrowException()) {
					throw new PipeRunException(this, msgString, e);
				} else {
					//This is used for the old console, where a message is displayed
					log.error(msgString, e);
					String msgCdataString = "<![CDATA[" + msgString + ": "+ e.getMessage() + "]]>";
					Message errorMessage = new Message("<error>" + msgCdataString + "</error>");
					return new PipeRunResult(getForward(), errorMessage);
				}
			}
		}
	}

}