/**
  * Marks a all folders synchronized to a device for re-synchronization
  * If no user is set all user which are synchronized for a device are marked for re-synchronization.
  * If no device id is set all devices of that user are marked for re-synchronization.
  * If no user and no device are set then ALL DEVICES are marked for resynchronization (use with care!).
  *
  * @param string    $user           (opt) user of the device
  * @param string    $devid          (opt)device id which should be wiped
  *
  * @return boolean
  * @access public
  */
 public static function ResyncDevice($user, $devid = false)
 {
     // search for target devices
     if ($devid === false) {
         $devicesIds = ZPush::GetStateMachine()->GetAllDevices($user);
         ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::ResyncDevice(): all '%d' devices for user '%s' found to be re-synchronized", count($devicesIds), $user));
         foreach ($devicesIds as $deviceid) {
             if (!self::ResyncDevice($user, $deviceid)) {
                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): wipe devices failed for device '%s' of user '%s'. Aborting", $deviceid, $user));
                 return false;
             }
         }
     } else {
         // get devicedata
         try {
             $devicedata = ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA);
         } catch (StateNotFoundException $e) {
             ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): state for device '%s' can not be found", $devid));
             return false;
         }
         // loop through all users which currently use this device
         if ($user === false && $devicedata instanceof StateObject && isset($devicedata->devices) && is_array($devicedata->devices) && count($devicedata->devices) > 1) {
             foreach (array_keys($devicedata) as $aUser) {
                 if (!self::ResyncDevice($aUser, $devid)) {
                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): re-synchronization failed for device '%s' of user '%s'. Aborting", $devid, $aUser));
                     return false;
                 }
             }
         }
         // load device data
         $device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
         try {
             $device->SetData($devicedata, false);
             if ($device->IsNewDevice()) {
                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): data of user '%s' not synchronized on device '%s'. Aborting.", $user, $devid));
                 return false;
             }
             // delete all uuids
             foreach ($device->GetAllFolderIds() as $folderid) {
                 StateManager::UnLinkState($device, $folderid);
             }
             // remove hierarchcache
             StateManager::UnLinkState($device, false);
             ZPush::GetStateMachine()->SetState($device->GetData(), $devid, IStateMachine::DEVICEDATA);
             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::ResyncDevice(): all folders synchronized to device '%s' of user '%s' marked to be re-synchronized.", $devid, $user));
         } catch (StateNotFoundException $e) {
             ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): state for device '%s' of user '%s' can not be found or saved", $devid, $user));
             return false;
         }
     }
     return true;
 }
 /**
  * Removes all linked states from a device.
  * During next requests a full resync is triggered.
  *
  * @access public
  * @return boolean
  */
 public function ForceFullResync()
 {
     ZLog::Write(LOGLEVEL_INFO, "Full device resync requested");
     // delete hierarchy states
     StateManager::UnLinkState($this->device, false);
     // delete all other uuids
     foreach ($this->device->GetAllFolderIds() as $folderid) {
         $uuid = StateManager::UnLinkState($this->device, $folderid);
     }
     return true;
 }