@Override
  protected void processResponse(String response) throws Exception {
    Set<Long> remoteSyncSiteIds = new HashSet<Long>();

    ObjectMapper objectMapper = new ObjectMapper();

    List<SyncSite> remoteSyncSites =
        objectMapper.readValue(response, new TypeReference<List<SyncSite>>() {});

    for (SyncSite remoteSyncSite : remoteSyncSites) {
      SyncSite localSyncSite =
          SyncSiteService.fetchSyncSite(remoteSyncSite.getGroupId(), getSyncAccountId());

      if (localSyncSite == null) {
        SyncAccount syncAccount = SyncAccountService.fetchSyncAccount(getSyncAccountId());

        remoteSyncSite.setFilePathName(
            syncAccount.getFilePathName() + "/" + remoteSyncSite.getName());

        remoteSyncSite.setSyncAccountId(getSyncAccountId());

        SyncSiteService.update(remoteSyncSite);

        remoteSyncSiteIds.add(remoteSyncSite.getSyncSiteId());
      } else {
        localSyncSite.setDescription(remoteSyncSite.getDescription());
        localSyncSite.setFriendlyURL(remoteSyncSite.getFriendlyURL());
        localSyncSite.setName(remoteSyncSite.getName());
        localSyncSite.setType(remoteSyncSite.getType());
        localSyncSite.setTypeSettings(remoteSyncSite.getTypeSettings());
        localSyncSite.setSite(remoteSyncSite.getSite());

        SyncSiteService.update(localSyncSite);

        remoteSyncSiteIds.add(localSyncSite.getSyncSiteId());
      }
    }

    List<SyncSite> localSyncSites = SyncSiteService.findSyncSites(getSyncAccountId());

    for (SyncSite localSyncSite : localSyncSites) {
      if (remoteSyncSiteIds.contains(localSyncSite.getSyncSiteId())) {
        continue;
      }

      SyncSiteService.deleteSyncSite(localSyncSite.getSyncSiteId());
    }
  }
  public static SyncAccount addSyncAccount(
      String filePathName,
      String login,
      int maxConnections,
      String name,
      String password,
      int pollInterval,
      SyncSite[] syncSites,
      boolean trustSelfSigned,
      String url)
      throws Exception {

    // Sync account

    SyncAccount syncAccount = new SyncAccount();

    syncAccount.setFilePathName(filePathName);
    syncAccount.setLogin(login);
    syncAccount.setMaxConnections(maxConnections);
    syncAccount.setName(name);
    syncAccount.setPassword(Encryptor.encrypt(password));
    syncAccount.setPollInterval(pollInterval);
    syncAccount.setTrustSelfSigned(trustSelfSigned);
    syncAccount.setUrl(url);

    _syncAccountPersistence.create(syncAccount);

    // Sync file

    Files.createDirectories(Paths.get(filePathName));

    SyncFileService.addSyncFile(
        null,
        null,
        filePathName,
        FileUtil.getFileKey(filePathName),
        filePathName,
        null,
        filePathName,
        0,
        0,
        syncAccount.getSyncAccountId(),
        SyncFile.TYPE_SYSTEM);

    // Sync sites

    if (syncSites != null) {
      for (SyncSite syncSite : syncSites) {
        String syncSiteName = syncSite.getName();

        if (!FileUtil.isValidFileName(syncSiteName)) {
          syncSiteName = String.valueOf(syncSite.getGroupId());
        }

        syncSite.setFilePathName(syncAccount.getFilePathName() + "/" + syncSiteName);

        syncSite.setSyncAccountId(syncAccount.getSyncAccountId());

        SyncSiteService.update(syncSite);
      }
    }

    return syncAccount;
  }