src/main/java/org/sikuli/slides/api/actions/RetryAction.java
public void execute(Context context) throws ActionExecutionException{
		Action action = checkNotNull(getChild());
		
		// start a timer that will set the timesup flag to true
		Timer timer = new Timer();
		TimerTask task = new TimerTask(){
			@Override
			public void run() {
				timesupFlag = true;
			}
		};
		if (timeout < Long.MAX_VALUE){
			timer.schedule(task, timeout);
		}
		
		ActionExecutionException exception = null;
		
		timesupFlag = false;
		stopFlag = false;
		while(!timesupFlag && !stopFlag){
			try{
				action.execute(context);
				return;
			}catch(ActionExecutionException e){				
				exception = e;
			}
			synchronized (this){
				try {
					this.wait(interval);
				} catch (InterruptedException e) {
				}
			}
		}

		if (timesupFlag){
			// execution does not succeed before timeout
			// rethrow the exception
			if (exception != null)
				throw exception;
		}				
	}
public void execute(Context context) throws ActionExecutionException{
		Action action = checkNotNull(getChild());
		
		// start a timer that will set the timesup flag to true
		Timer timer = new Timer();
		TimerTask task = new TimerTask(){
			@Override
			public void run() {
				timesupFlag = true;
			}
		};
		if (timeout < Long.MAX_VALUE){
			timer.schedule(task, timeout);
		}
		
		ActionExecutionException exception = null;
		
		timesupFlag = false;
		stopFlag = false;
		while(!timesupFlag && !stopFlag){
			try{
				action.execute(context);
				return;
			}catch(ActionExecutionException e){				
				exception = e;
			}
			synchronized (this){
				try {
					this.wait(interval);
				} catch (InterruptedException e) {
				}
			}
		}

		if (timesupFlag){
			// execution does not succeed before timeout
			// rethrow the exception
			if (exception != null)
				throw exception;
		}				
	}
Execute and wait for execution to finish