@Override
  public void onUpdate(SyncAccount syncAccount, Map<String, Object> originalValues) {

    if (!originalValues.containsKey("active")) {
      return;
    }

    List<Long> activeSyncAccountIds = SyncAccountService.getActiveSyncAccountIds();

    if ((Boolean) originalValues.get("active")) {
      activeSyncAccountIds.remove(syncAccount.getSyncAccountId());

      try {
        SyncEngine.cancelSyncAccountTasks(syncAccount.getSyncAccountId());
      } catch (Exception e) {
        _logger.error(e.getMessage(), e);
      }
    } else {
      activeSyncAccountIds.add(syncAccount.getSyncAccountId());

      try {
        SyncEngine.scheduleSyncAccountTasks(syncAccount.getSyncAccountId());
      } catch (Exception e) {
        _logger.error(e.getMessage(), e);
      }
    }

    SyncAccountService.setActiveSyncAccountIds(activeSyncAccountIds);
  }
  protected static void doDeleteSyncFile(SyncFile syncFile, boolean notify) throws SQLException {

    if (syncFile.isFile()) {
      final Path filePath = IODeltaUtil.getChecksumsFilePath(syncFile);

      Runnable runnable =
          new Runnable() {

            @Override
            public void run() {
              try {
                Files.deleteIfExists(filePath);
              } catch (IOException ioe) {
                _logger.error(ioe.getMessage(), ioe);
              }
            }
          };

      ExecutorService executorService = SyncEngine.getExecutorService();

      executorService.execute(runnable);
    }

    _syncFilePersistence.delete(syncFile, notify);
  }
  @Override
  public void onRemove(SyncAccount syncAccount) {
    List<Long> activeSyncAccountIds = SyncAccountService.getActiveSyncAccountIds();

    activeSyncAccountIds.remove(syncAccount.getSyncAccountId());

    SyncAccountService.setActiveSyncAccountIds(activeSyncAccountIds);

    try {
      SyncEngine.cancelSyncAccountTasks(syncAccount.getSyncAccountId());
    } catch (Exception e) {
      _logger.error(e.getMessage(), e);
    }
  }
/** @author Michael Young */
public class SyncWatchEventProcessor implements Runnable {

  public SyncWatchEventProcessor(long syncAccountId) {
    _syncAccountId = syncAccountId;

    SyncFileModelListener syncFileModelListener =
        new SyncFileModelListener() {

          @Override
          public void onRemove(SyncFile syncFile) {
            _dependentSyncWatchEventsMaps.remove(syncFile.getFilePathName());

            _pendingTypePKSyncFileIds.remove(syncFile.getTypePK());
          }

          @Override
          public void onUpdate(SyncFile syncFile, Map<String, Object> originalValues) {

            if ((syncFile.getSyncAccountId() != _syncAccountId)
                || (syncFile.getTypePK() == 0)
                || (!originalValues.containsKey("state")
                    && !originalValues.containsKey("typePK"))) {

              return;
            }

            List<SyncWatchEvent> syncWatchEvents =
                _dependentSyncWatchEventsMaps.remove(syncFile.getFilePathName());

            if (syncWatchEvents == null) {
              return;
            }

            if (syncFile.getTypePK() > 0) {
              _pendingTypePKSyncFileIds.remove(syncFile.getSyncFileId());
            }

            for (SyncWatchEvent syncWatchEvent : syncWatchEvents) {
              try {
                if (_logger.isDebugEnabled()) {
                  _logger.debug(
                      "Processing queued event {} {}",
                      syncWatchEvent.getFilePathName(),
                      syncWatchEvent.getEventType());
                }

                processSyncWatchEvent(syncWatchEvent);
              } catch (Exception e) {
                _logger.error(e.getMessage(), e);
              }
            }
          }
        };

    SyncFileService.registerModelListener(syncFileModelListener);
  }

  public boolean isInProgress() {
    if (SyncWatchEventService.hasSyncWatchEvents(_syncAccountId)
        || SyncFileService.hasSyncFiles(_syncAccountId, SyncFile.UI_EVENT_DOWNLOADING)
        || SyncFileService.hasSyncFiles(_syncAccountId, SyncFile.UI_EVENT_UPLOADING)) {

      return true;
    }

    return false;
  }

  @Override
  public void run() {
    try {
      SyncAccount syncAccount = SyncAccountService.fetchSyncAccount(_syncAccountId);

      if (syncAccount.getState() != SyncAccount.STATE_CONNECTED) {
        return;
      }

      doRun();
    } catch (Exception e) {
      _logger.error(e.getMessage(), e);
    }

    BatchEventManager.fireBatchEvents();
  }

  protected void addFile(SyncWatchEvent syncWatchEvent) throws Exception {
    final Path targetFilePath = Paths.get(syncWatchEvent.getFilePathName());

    if (FileUtil.notExists(targetFilePath)
        || sanitizeFileName(targetFilePath)
        || isInErrorState(targetFilePath)) {

      return;
    }

    Path parentTargetFilePath = targetFilePath.getParent();

    final SyncFile parentSyncFile = SyncFileService.fetchSyncFile(parentTargetFilePath.toString());

    if ((parentSyncFile == null)
        || (!parentSyncFile.isSystem() && (parentSyncFile.getTypePK() == 0))) {

      queueSyncWatchEvent(parentTargetFilePath.toString(), syncWatchEvent);

      return;
    }

    SyncFile syncFile = SyncFileService.fetchSyncFile(targetFilePath.toString());

    if (syncFile == null) {
      syncFile = SyncFileService.fetchSyncFile(FileKeyUtil.getFileKey(targetFilePath));

      if (!verifySite(syncFile, parentSyncFile)) {
        syncFile = null;
      }
    }

    if (syncFile == null) {
      Runnable runnable =
          new Runnable() {

            @Override
            public void run() {
              try {
                SyncSite syncSite =
                    SyncSiteService.fetchSyncSite(parentSyncFile.getRepositoryId(), _syncAccountId);

                if ((syncSite == null)
                    || !syncSite.isActive()
                    || !FileUtil.checkFilePath(targetFilePath)) {

                  return;
                }

                SyncFileService.addFileSyncFile(
                    targetFilePath,
                    parentSyncFile.getTypePK(),
                    parentSyncFile.getRepositoryId(),
                    _syncAccountId);
              } catch (Exception e) {
                if (SyncFileService.fetchSyncFile(targetFilePath.toString()) == null) {

                  _logger.error(e.getMessage(), e);
                }
              }
            }
          };

      _executorService.execute(runnable);

      return;
    }

    Path sourceFilePath = Paths.get(syncFile.getFilePathName());

    if (targetFilePath.equals(sourceFilePath)) {
      if (isPendingTypePK(syncFile) || (syncFile.getState() == SyncFile.STATE_IN_PROGRESS)) {

        queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

        return;
      }

      if (FileUtil.isModified(syncFile)) {
        SyncFileService.updateFileSyncFile(targetFilePath, _syncAccountId, syncFile);
      }
    } else if (FileUtil.exists(sourceFilePath)) {
      try {
        if ((Files.size(targetFilePath) == 0)
            || FileUtil.isModified(syncFile, targetFilePath)
            || isInErrorState(sourceFilePath)) {

          SyncFileService.addFileSyncFile(
              targetFilePath,
              parentSyncFile.getTypePK(),
              parentSyncFile.getRepositoryId(),
              _syncAccountId);
        } else {
          SyncFileService.copySyncFile(
              syncFile,
              targetFilePath,
              parentSyncFile.getTypePK(),
              parentSyncFile.getRepositoryId(),
              _syncAccountId);
        }
      } catch (Exception e) {
        if (SyncFileService.fetchSyncFile(targetFilePath.toString()) == null) {

          _logger.error(e.getMessage(), e);
        }
      }

      return;
    } else if (parentTargetFilePath.equals(sourceFilePath.getParent())) {
      if (isPendingTypePK(syncFile) || (syncFile.getState() == SyncFile.STATE_IN_PROGRESS)) {

        queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

        return;
      }

      SyncFileService.updateFileSyncFile(targetFilePath, _syncAccountId, syncFile);
    } else {
      if (isPendingTypePK(syncFile) || (syncFile.getState() == SyncFile.STATE_IN_PROGRESS)) {

        queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

        return;
      }

      SyncFileService.moveFileSyncFile(
          targetFilePath, parentSyncFile.getTypePK(), _syncAccountId, syncFile);

      Path sourceFileNameFilePath = sourceFilePath.getFileName();

      if (!sourceFileNameFilePath.equals(targetFilePath.getFileName())) {
        SyncFileService.updateFileSyncFile(targetFilePath, _syncAccountId, syncFile);
      }
    }

    SyncAccount syncAccount = SyncAccountService.fetchSyncAccount(_syncAccountId);

    if (syncAccount.getState() == SyncAccount.STATE_CONNECTED) {
      SyncWatchEvent relatedSyncWatchEvent =
          SyncWatchEventService.fetchSyncWatchEvent(
              SyncWatchEvent.EVENT_TYPE_DELETE,
              syncWatchEvent.getFilePathName(),
              syncWatchEvent.getTimestamp());

      if (relatedSyncWatchEvent != null) {
        _processedSyncWatchEventIds.add(relatedSyncWatchEvent.getSyncWatchEventId());
      }
    }
  }

  protected void addFolder(SyncWatchEvent syncWatchEvent) throws Exception {
    Path targetFilePath = Paths.get(syncWatchEvent.getFilePathName());

    if (sanitizeFileName(targetFilePath) || isInErrorState(targetFilePath)) {

      return;
    }

    Path parentTargetFilePath = targetFilePath.getParent();

    SyncFile parentSyncFile = SyncFileService.fetchSyncFile(parentTargetFilePath.toString());

    if ((parentSyncFile == null)
        || (!parentSyncFile.isSystem() && (parentSyncFile.getTypePK() == 0))) {

      queueSyncWatchEvent(parentTargetFilePath.toString(), syncWatchEvent);

      return;
    }

    SyncFile syncFile = SyncFileService.fetchSyncFile(targetFilePath.toString());

    if (syncFile == null) {
      syncFile = SyncFileService.fetchSyncFile(FileKeyUtil.getFileKey(targetFilePath));

      if (!verifySite(syncFile, parentSyncFile)) {
        syncFile = null;
      }
    }

    if (syncFile == null) {
      SyncFileService.addFolderSyncFile(
          targetFilePath,
          parentSyncFile.getTypePK(),
          parentSyncFile.getRepositoryId(),
          _syncAccountId);

      return;
    }

    Path sourceFilePath = Paths.get(syncFile.getFilePathName());

    if (targetFilePath.equals(sourceFilePath)) {
      FileKeyUtil.writeFileKey(targetFilePath, String.valueOf(syncFile.getSyncFileId()), true);
    } else if (FileUtil.exists(sourceFilePath)) {
      SyncFileService.addFolderSyncFile(
          targetFilePath,
          parentSyncFile.getTypePK(),
          parentSyncFile.getRepositoryId(),
          _syncAccountId);

      return;
    } else if (parentTargetFilePath.equals(sourceFilePath.getParent())) {
      if (isPendingTypePK(syncFile)) {
        queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

        return;
      }

      SyncFileService.updateFolderSyncFile(targetFilePath, _syncAccountId, syncFile);
    } else {
      if (isPendingTypePK(syncFile)) {
        queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

        return;
      }

      SyncFileService.moveFolderSyncFile(
          targetFilePath, parentSyncFile.getTypePK(), _syncAccountId, syncFile);

      Path sourceFileNameFilePath = sourceFilePath.getFileName();

      if (!sourceFileNameFilePath.equals(targetFilePath.getFileName())) {
        SyncFileService.updateFolderSyncFile(targetFilePath, _syncAccountId, syncFile);
      }
    }

    SyncAccount syncAccount = SyncAccountService.fetchSyncAccount(_syncAccountId);

    if (syncAccount.getState() == SyncAccount.STATE_CONNECTED) {
      SyncWatchEvent relatedSyncWatchEvent =
          SyncWatchEventService.fetchSyncWatchEvent(
              SyncWatchEvent.EVENT_TYPE_DELETE,
              syncWatchEvent.getFilePathName(),
              syncWatchEvent.getTimestamp());

      if (relatedSyncWatchEvent != null) {
        _processedSyncWatchEventIds.add(relatedSyncWatchEvent.getSyncWatchEventId());
      }
    }
  }

  protected void deleteFile(SyncWatchEvent syncWatchEvent) throws Exception {
    Path filePath = Paths.get(syncWatchEvent.getFilePathName());

    SyncFile syncFile = SyncFileService.fetchSyncFile(filePath.toString());

    if ((syncFile == null) || !FileUtil.notExists(Paths.get(syncFile.getFilePathName()))) {

      return;
    } else if ((syncFile.getState() == SyncFile.STATE_ERROR)
        || (syncFile.getState() == SyncFile.STATE_UNSYNCED)) {

      SyncFileService.deleteSyncFile(syncFile, false);

      return;
    } else if (syncFile.getState() == SyncFile.STATE_IN_PROGRESS) {
      Set<Event> events = FileEventManager.getEvents(syncFile.getSyncFileId());

      for (Event event : events) {
        event.cancel();
      }

      if (isPendingTypePK(syncFile)) {
        SyncFileService.deleteSyncFile(syncFile);

        return;
      }
    } else if (isPendingTypePK(syncFile)) {
      queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

      return;
    }

    String type = syncFile.getType();

    if (type.equals(SyncFile.TYPE_FILE)) {
      FileEventUtil.deleteFile(_syncAccountId, syncFile);
    } else {
      FileEventUtil.deleteFolder(_syncAccountId, syncFile);
    }
  }

  protected void doRun() throws Exception {
    SyncWatchEvent lastSyncWatchEvent = SyncWatchEventService.getLastSyncWatchEvent(_syncAccountId);

    if (lastSyncWatchEvent == null) {
      return;
    }

    long delta = System.currentTimeMillis() - lastSyncWatchEvent.getTimestamp();

    if (delta <= 500) {
      SyncEngineUtil.fireSyncEngineStateChanged(
          _syncAccountId, SyncEngineUtil.SYNC_ENGINE_STATE_PROCESSING);

      return;
    }

    if (_logger.isTraceEnabled()) {
      _logger.trace("Processing Sync watch events");
    }

    _pendingTypePKSyncFileIds.clear();

    List<SyncWatchEvent> syncWatchEvents = null;

    if (OSDetector.isApple()) {
      syncWatchEvents = SyncWatchEventService.findBySyncAccountId(_syncAccountId);
    } else {
      syncWatchEvents =
          SyncWatchEventService.findBySyncAccountId(_syncAccountId, "eventType", true);
    }

    for (SyncWatchEvent syncWatchEvent : syncWatchEvents) {
      processSyncWatchEvent(syncWatchEvent);
    }

    for (Map.Entry<String, List<SyncWatchEvent>> entry : _dependentSyncWatchEventsMaps.entrySet()) {

      SyncFile syncFile = SyncFileService.fetchSyncFile(entry.getKey());

      if ((syncFile != null) && (syncFile.getTypePK() > 0)) {
        for (SyncWatchEvent syncWatchEvent : entry.getValue()) {
          processSyncWatchEvent(syncWatchEvent);
        }
      }
    }

    SyncEngineUtil.fireSyncEngineStateChanged(
        _syncAccountId, SyncEngineUtil.SYNC_ENGINE_STATE_PROCESSED);

    _processedSyncWatchEventIds.clear();
  }

  protected boolean isInErrorState(Path filePath) {
    while (true) {
      if (filePath == null) {
        return false;
      }

      SyncFile syncFile = SyncFileService.fetchSyncFile(filePath.toString());

      if (syncFile != null) {
        if (syncFile.isSystem()) {
          break;
        }

        if (syncFile.getState() == SyncFile.STATE_ERROR) {
          return true;
        }
      }

      filePath = filePath.getParent();
    }

    return false;
  }

  protected boolean isPendingTypePK(SyncFile syncFile) {
    if (_pendingTypePKSyncFileIds.contains(syncFile.getSyncFileId())) {
      return true;
    } else if (syncFile.getTypePK() == 0) {
      _pendingTypePKSyncFileIds.add(syncFile.getSyncFileId());

      return true;
    }

    return false;
  }

  protected void modifyFile(SyncWatchEvent syncWatchEvent) throws Exception {
    Path filePath = Paths.get(syncWatchEvent.getFilePathName());

    SyncFile syncFile = SyncFileService.fetchSyncFile(filePath.toString());

    if (syncFile == null) {
      return;
    } else if (isPendingTypePK(syncFile) || (syncFile.getState() == SyncFile.STATE_IN_PROGRESS)) {

      queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

      return;
    } else if (!FileUtil.isModified(syncFile)) {
      return;
    }

    SyncFileService.updateFileSyncFile(filePath, _syncAccountId, syncFile);
  }

  protected void moveFile(SyncWatchEvent syncWatchEvent) throws Exception {
    Path targetFilePath = Paths.get(syncWatchEvent.getFilePathName());

    if (FileUtil.notExists(targetFilePath)
        || sanitizeFileName(targetFilePath)
        || isInErrorState(targetFilePath)) {

      return;
    }

    Path parentTargetFilePath = targetFilePath.getParent();

    SyncFile parentSyncFile = SyncFileService.fetchSyncFile(parentTargetFilePath.toString());

    if ((parentSyncFile == null)
        || (!parentSyncFile.isSystem() && (parentSyncFile.getTypePK() == 0))) {

      queueSyncWatchEvent(parentTargetFilePath.toString(), syncWatchEvent);

      return;
    }

    Path sourceFilePath = Paths.get(syncWatchEvent.getPreviousFilePathName());

    SyncFile sourceSyncFile = SyncFileService.fetchSyncFile(sourceFilePath.toString());

    SyncFile targetSyncFile = SyncFileService.fetchSyncFile(targetFilePath.toString());

    if ((sourceSyncFile == null) || (targetSyncFile != null)) {
      if (Files.isDirectory(targetFilePath)) {
        addFolder(syncWatchEvent);
      } else {
        addFile(syncWatchEvent);
      }

      return;
    } else if (isPendingTypePK(sourceSyncFile)) {
      queueSyncWatchEvent(sourceSyncFile.getFilePathName(), syncWatchEvent);

      return;
    }

    String fileType = sourceSyncFile.getType();

    if (fileType.equals(SyncFile.TYPE_FILE)) {
      SyncFileService.moveFileSyncFile(
          targetFilePath, parentSyncFile.getTypePK(), _syncAccountId, sourceSyncFile);
    } else {
      SyncFileService.moveFolderSyncFile(
          targetFilePath, parentSyncFile.getTypePK(), _syncAccountId, sourceSyncFile);
    }

    renameFile(syncWatchEvent);
  }

  protected synchronized void processSyncWatchEvent(SyncWatchEvent syncWatchEvent)
      throws Exception {

    SyncAccount syncAccount = SyncAccountService.fetchSyncAccount(_syncAccountId);

    if (syncAccount.getState() != SyncAccount.STATE_CONNECTED) {
      return;
    }

    if (_processedSyncWatchEventIds.contains(syncWatchEvent.getSyncWatchEventId())) {

      SyncWatchEventService.deleteSyncWatchEvent(syncWatchEvent.getSyncWatchEventId());

      return;
    }

    String eventType = syncWatchEvent.getEventType();

    if (eventType.equals(SyncWatchEvent.EVENT_TYPE_RENAME_FROM)) {
      eventType = SyncWatchEvent.EVENT_TYPE_DELETE;

      syncWatchEvent.setEventType(eventType);

      SyncWatchEventService.update(syncWatchEvent);
    }

    if (_logger.isDebugEnabled()) {
      _logger.debug("Processing Sync watch event {}", syncWatchEvent.toString());
    }

    String fileType = syncWatchEvent.getFileType();

    if (eventType.equals(SyncWatchEvent.EVENT_TYPE_CREATE)) {
      if (fileType.equals(SyncFile.TYPE_FILE)) {
        SyncWatchEvent duplicateSyncWatchEvent = null;

        if (OSDetector.isApple()) {
          duplicateSyncWatchEvent =
              SyncWatchEventService.fetchDuplicateSyncWatchEvent(syncWatchEvent);
        }

        if (duplicateSyncWatchEvent != null) {
          if (_logger.isDebugEnabled()) {
            _logger.debug("Skipping outdated Sync watch event");
          }
        } else {
          addFile(syncWatchEvent);
        }
      } else {
        addFolder(syncWatchEvent);
      }
    } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_DELETE)) {
      deleteFile(syncWatchEvent);
    } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_MODIFY)) {
      SyncWatchEvent duplicateSyncWatchEvent =
          SyncWatchEventService.fetchDuplicateSyncWatchEvent(syncWatchEvent);

      if (duplicateSyncWatchEvent != null) {
        if (_logger.isDebugEnabled()) {
          _logger.debug("Skipping outdated Sync watch event");
        }
      } else {
        modifyFile(syncWatchEvent);
      }
    } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_MOVE)) {
      moveFile(syncWatchEvent);
    } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_RENAME)) {
      renameFile(syncWatchEvent);
    }

    syncAccount = SyncAccountService.fetchSyncAccount(_syncAccountId);

    if (syncAccount.getState() == SyncAccount.STATE_CONNECTED) {
      SyncWatchEventService.deleteSyncWatchEvent(syncWatchEvent.getSyncWatchEventId());
    }
  }

  protected void queueSyncWatchEvent(String parentFilePathName, SyncWatchEvent syncWatchEvent) {

    List<SyncWatchEvent> syncWatchEvents = _dependentSyncWatchEventsMaps.get(parentFilePathName);

    if (syncWatchEvents == null) {
      syncWatchEvents = new ArrayList<>();

      _dependentSyncWatchEventsMaps.put(parentFilePathName, syncWatchEvents);
    } else {
      String eventType = syncWatchEvent.getEventType();
      String filePathName = syncWatchEvent.getFilePathName();

      SyncWatchEvent lastSyncWatchEvent = syncWatchEvents.get(syncWatchEvents.size() - 1);

      if (filePathName.equals(lastSyncWatchEvent.getFilePathName())
          && eventType.equals(lastSyncWatchEvent.getEventType())) {

        return;
      }
    }

    if (_logger.isDebugEnabled()) {
      _logger.debug(
          "Queueing event {} {}", syncWatchEvent.getEventType(), syncWatchEvent.getFilePathName());
    }

    if (!syncWatchEvents.contains(syncWatchEvent)) {
      syncWatchEvents.add(syncWatchEvent);
    }
  }

  protected void renameFile(SyncWatchEvent syncWatchEvent) throws Exception {
    Path sourceFilePath = Paths.get(syncWatchEvent.getPreviousFilePathName());

    SyncFile syncFile = SyncFileService.fetchSyncFile(sourceFilePath.toString());

    Path targetFilePath = Paths.get(syncWatchEvent.getFilePathName());

    if (sanitizeFileName(targetFilePath)) {
      return;
    }

    if (syncFile == null) {
      if (Files.isDirectory(targetFilePath)) {
        addFolder(syncWatchEvent);
      } else {
        addFile(syncWatchEvent);
      }

      return;
    } else if (isPendingTypePK(syncFile)) {
      queueSyncWatchEvent(syncFile.getFilePathName(), syncWatchEvent);

      return;
    }

    String fileType = syncFile.getType();

    if (fileType.equals(SyncFile.TYPE_FILE)) {
      SyncFileService.renameFileSyncFile(targetFilePath, _syncAccountId, syncFile);
    } else {
      SyncFileService.renameFolderSyncFile(targetFilePath, _syncAccountId, syncFile);
    }
  }

  protected boolean sanitizeFileName(Path filePath) {
    if (OSDetector.isWindows()) {
      return false;
    }

    String fileName = String.valueOf(filePath.getFileName());

    String sanitizedFileName =
        FileUtil.getSanitizedFileName(fileName, FilenameUtils.getExtension(fileName));

    if (!sanitizedFileName.equals(fileName)) {
      String sanitizedFilePathName =
          FileUtil.getFilePathName(String.valueOf(filePath.getParent()), sanitizedFileName);

      sanitizedFilePathName = FileUtil.getNextFilePathName(sanitizedFilePathName);

      FileUtil.checkFilePath(filePath);

      FileUtil.moveFile(filePath, Paths.get(sanitizedFilePathName));

      return true;
    }

    return false;
  }

  protected boolean verifySite(SyncFile syncFile, SyncFile parentSyncFile) {
    if ((syncFile != null)
        && ((syncFile.getRepositoryId() != parentSyncFile.getRepositoryId())
            || (syncFile.getSyncAccountId() != parentSyncFile.getSyncAccountId()))) {

      return false;
    }

    return true;
  }

  private static final Logger _logger = LoggerFactory.getLogger(SyncWatchEventProcessor.class);

  private static final ExecutorService _executorService = SyncEngine.getExecutorService();

  private final Map<String, List<SyncWatchEvent>> _dependentSyncWatchEventsMaps =
      new ConcurrentHashMap<>();
  private final Set<Long> _pendingTypePKSyncFileIds = new HashSet<>();
  private final Set<Long> _processedSyncWatchEventIds = new HashSet<>();
  private final long _syncAccountId;
}