docs: public void run() {
  		
  		task.setSetTimerTransactionalAction(null);
  		
  		if (!canceled) {
  			
  			TimerTask previousTask = scheduler.getLocalRunningTasksMap().putIfAbsent(task.getData().getTaskID(), task);
  			if(previousTask != null) {
  				if (logger.isDebugEnabled()) {
  					logger.debug("A task with id " + task.getData().getTaskID() + " has already been added to the local tasks, not rescheduling");
  				}
  			}
  			
  			final TimerTaskData taskData = task.getData();
  			// calculate delay
  			long delay = taskData.getStartTime() - System.currentTimeMillis();
  			if (delay < 0) {
  				delay = 0;
  			}
  			
  			try {
  				// schedule runnable
  				if (taskData.getPeriod() < 0) {
  					if (logger.isDebugEnabled()) {
  						logger.debug("Scheduling one-shot timer with id "
  								+ task.getData().getTaskID() + ", delay " + delay);
  					}
  					task.setScheduledFuture(scheduler.getExecutor().schedule(task, delay, TimeUnit.MILLISECONDS));
  				} else {
  					if (logger.isDebugEnabled()) {
  						logger.debug("Scheduling periodic timer with id "
  								+ task.getData().getTaskID() + ", scheduling strategy " + taskData.getPeriodicScheduleStrategy() + ", delay " + delay + ", period " + taskData.getPeriod());
  					}
  					if (taskData.getPeriodicScheduleStrategy() == PeriodicScheduleStrategy.withFixedDelay) {
  						task.setScheduledFuture(scheduler.getExecutor().scheduleWithFixedDelay(task, delay, taskData.getPeriod(),TimeUnit.MILLISECONDS));
  					}
  					else {
  						// default
  						task.setScheduledFuture(scheduler.getExecutor().scheduleAtFixedRate(task, delay, taskData.getPeriod(),TimeUnit.MILLISECONDS));
  					}					
  				}		
  			} catch (Throwable e) {
  				logger.error(e.getMessage(), e);
  				scheduler.remove(taskData.getTaskID(),true);
  			}
  		} else {
  			if (logger.isDebugEnabled()) {
  				logger.debug("Canceled scheduling periodic timer with id "
  						+ task.getData().getTaskID());
  			}
  		}
  	}