public static PropertyTimer createPropertyTimer(
     AbstractProperty property, TIMER_ACTION action, long period) {
   if (property == null) return null;
   if (action == TIMER_ACTION.VALIDATE && !(property instanceof ValueProperty<?>)) return null;
   PropertyTimer propertyTimer = new PropertyTimer(action, period, property);
   timerService.scheduleAtFixedRate(propertyTimer, 0, period);
   synchronized (property) {
     PropertyTimerHolder holder =
         (PropertyTimerHolder) property.getAdditionalInfo(AbstractProperty.TIMERS);
     if (holder == null) {
       PropertyTimer oldTimer = (PropertyTimer) property.getAdditionalInfo(AbstractProperty.TIMER);
       if (oldTimer != null) {
         holder = new PropertyTimerHolder();
         holder.addPropertyTimer(oldTimer);
         holder.addPropertyTimer(propertyTimer);
         property.setAdditionalInfo(AbstractProperty.TIMER, null);
         property.setAdditionalInfo(AbstractProperty.TIMERS, holder);
       } else {
         property.setAdditionalInfo(AbstractProperty.TIMER, propertyTimer);
       }
     } else {
       holder.addPropertyTimer(propertyTimer);
     }
     property.getAdditionalInfo(AbstractProperty.TIMER);
     property.getAdditionalInfo(AbstractProperty.TIMERS);
   }
   return propertyTimer;
 }
 public static synchronized PropertyTimer[] getTimersForProperty(AbstractProperty property) {
   if (property == null) return null;
   PropertyTimer oneTimer = (PropertyTimer) property.getAdditionalInfo(AbstractProperty.TIMER);
   if (oneTimer != null) return new PropertyTimer[] {oneTimer};
   PropertyTimerHolder holder =
       (PropertyTimerHolder) property.getAdditionalInfo(AbstractProperty.TIMERS);
   if (holder != null) return holder.getTimers();
   return null;
 }
 public void destroy() {
   if (cancel()) {
     timerService.purge();
     synchronized (property) {
       PropertyTimer oneTimer = (PropertyTimer) property.getAdditionalInfo(AbstractProperty.TIMER);
       if (oneTimer == null) {
         PropertyTimerHolder holder =
             (PropertyTimerHolder) property.getAdditionalInfo(AbstractProperty.TIMERS);
         if (holder != null) {
           holder.removePropertyTimer(this);
         }
       } else {
         property.setAdditionalInfo(AbstractProperty.TIMER, null);
       }
     }
   }
 }