@Override
  public void processResponse(String response) throws Exception {
    SyncFile remoteSyncFile = JSONUtil.readValue(response, SyncFile.class);

    SyncFile localSyncFile = getLocalSyncFile();

    if (localSyncFile == null) {
      return;
    }

    localSyncFile.setModifiedTime(remoteSyncFile.getModifiedTime());
    localSyncFile.setParentFolderId(remoteSyncFile.getParentFolderId());
    localSyncFile.setSize(remoteSyncFile.getSize());
    localSyncFile.setState(SyncFile.STATE_SYNCED);
    localSyncFile.setUiEvent(SyncFile.UI_EVENT_UPLOADED);
    localSyncFile.setVersion(remoteSyncFile.getVersion());
    localSyncFile.setVersionId(remoteSyncFile.getVersionId());

    SyncFileService.update(localSyncFile);
  }
  @Override
  protected void doHandleResponse(HttpResponse httpResponse) throws Exception {

    final Session session = SessionManager.getSession(getSyncAccountId());

    Header tokenHeader = httpResponse.getFirstHeader("Sync-JWT");

    if (tokenHeader != null) {
      session.setToken(tokenHeader.getValue());
    }

    Map<String, DownloadFileHandler> handlers =
        (Map<String, DownloadFileHandler>) getParameterValue("handlers");

    InputStream inputStream = null;

    try {
      HttpEntity httpEntity = httpResponse.getEntity();

      inputStream =
          new CountingInputStream(httpEntity.getContent()) {

            @Override
            protected synchronized void afterRead(int n) {
              session.incrementDownloadedBytes(n);

              super.afterRead(n);
            }
          };

      ZipInputStream zipInputStream = new ZipInputStream(inputStream);

      ZipEntry zipEntry = null;

      while ((zipEntry = zipInputStream.getNextEntry()) != null) {
        String zipEntryName = zipEntry.getName();

        if (zipEntryName.equals("errors.json")) {
          JsonNode rootJsonNode = JSONUtil.readTree(zipInputStream);

          Iterator<Map.Entry<String, JsonNode>> fields = rootJsonNode.fields();

          while (fields.hasNext()) {
            Map.Entry<String, JsonNode> field = fields.next();

            Handler<Void> handler = handlers.get(field.getKey());

            JsonNode valueJsonNode = field.getValue();

            JsonNode exceptionJsonNode = valueJsonNode.get("exception");

            handler.handlePortalException(exceptionJsonNode.textValue());
          }

          break;
        }

        DownloadFileHandler downloadFileHandler = handlers.get(zipEntryName);

        SyncFile syncFile = (SyncFile) downloadFileHandler.getParameterValue("syncFile");

        if (downloadFileHandler.isUnsynced(syncFile)) {
          continue;
        }

        if (_logger.isTraceEnabled()) {
          _logger.trace(
              "Handling response {} file path {}",
              DownloadFileHandler.class.getSimpleName(),
              syncFile.getFilePathName());
        }

        try {
          downloadFileHandler.copyFile(
              syncFile,
              Paths.get(syncFile.getFilePathName()),
              new CloseShieldInputStream(zipInputStream),
              false);
        } catch (Exception e) {
          if (!isEventCancelled()) {
            _logger.error(e.getMessage(), e);
          }
        } finally {
          downloadFileHandler.removeEvent();
        }
      }
    } catch (Exception e) {
      if (!isEventCancelled() && _logger.isDebugEnabled()) {
        _logger.debug(e.getMessage(), e);
      }
    } finally {
      StreamUtil.cleanUp(inputStream);
    }
  }