/**
  * The end date of any round can depend on any token so always do a end date check
  * of the previous tokens
  *
  * @param \Gems_Tracker_RespondentTrack $respTrack The respondent track to check
  * @param \Gems_Tracker_Token $startToken The token to start at
  * @param int $userId Id of the user who takes the action (for logging)
  * @param \Gems_Tracker_Token $skipToken Optional token to skip in the recalculation
  * @return int The number of tokens changed by this code
  */
 public function checkTokensFrom(\Gems_Tracker_RespondentTrack $respTrack, \Gems_Tracker_Token $startToken, $userId, \Gems_Tracker_Token $skipToken = null)
 {
     $changed = parent::checkTokensFrom($respTrack, $startToken, $userId);
     // Now loop back
     $token = $startToken->getPreviousToken();
     while ($token) {
         // Change only not-completed tokens with a positive successcode where the end date is not set manually
         if ($token->hasSuccesCode() && !($token->isCompleted() || $token->isValidUntilManual()) && $token !== $skipToken) {
             // Only process the token when linked to a round
             if (array_key_exists($token->getRoundId(), $this->_rounds)) {
                 $round = $this->_rounds[$token->getRoundId()];
                 // Do not change valid from
                 $validFrom = $token->getValidFrom();
                 $untilDate = $this->getValidUntilDate($round['gro_valid_for_source'], $round['gro_valid_for_field'], $round['gro_valid_for_id'], $token, $respTrack, $validFrom);
                 $validUntil = $this->calculateUntilDate($untilDate, $round['gro_valid_for_unit'], $round['gro_valid_for_length']);
                 $changed += $token->setValidFrom($validFrom, $validUntil, $userId);
             }
         }
         $token = $token->getPreviousToken();
     }
     return $changed;
 }