/** Initialize the service. */
  @Override
  public void onCreate() {
    Log_OC.d(TAG, "onCreate");
    super.onCreate();

    mDownloadReceiver = new DownloadCompletedReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(FileDownloader.getDownloadAddedMessage());
    filter.addAction(FileDownloader.getDownloadFinishMessage());
    registerReceiver(mDownloadReceiver, filter);

    mFolderObserversMap = new HashMap<String, FolderObserver>();
  }
    @Override
    public void onReceive(Context context, Intent intent) {
      Log_OC.d(TAG, "Received broadcast intent " + intent);

      File downloadedFile = new File(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH));
      String parentPath = downloadedFile.getParent();
      FolderObserver observer = mFolderObserversMap.get(parentPath);
      if (observer != null) {
        if (intent.getAction().equals(FileDownloader.getDownloadFinishMessage())
            && downloadedFile.exists()) {
          // no matter if the download was successful or not; the
          // file could be down anyway due to a former download or upload
          observer.startWatching(downloadedFile.getName());
          Log_OC.d(TAG, "Resuming observance of " + downloadedFile.getAbsolutePath());

        } else if (intent.getAction().equals(FileDownloader.getDownloadAddedMessage())) {
          observer.stopWatching(downloadedFile.getName());
          Log_OC.d(TAG, "Pausing observance of " + downloadedFile.getAbsolutePath());
        }

      } else {
        Log_OC.d(TAG, "No observer for path " + downloadedFile.getAbsolutePath());
      }
    }
  /** Updates the view with all relevant details about that file. */
  public void updateFileDetails() {

    if (mFile != null && mAccount != null && mLayout == R.layout.file_details_fragment) {

      // set file details
      setFilename(mFile.getFileName());
      setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile.getMimetype()));
      setFilesize(mFile.getFileLength());
      if (ocVersionSupportsTimeCreated()) {
        setTimeCreated(mFile.getCreationTimestamp());
      }

      setTimeModified(mFile.getModificationTimestamp());

      CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync);
      cb.setChecked(mFile.keepInSync());

      // configure UI for depending upon local state of the file
      if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath())
          || FileUploader.isUploading(mAccount, mFile.getRemotePath())) {
        setButtonsForTransferring();

      } else if (mFile.isDown()) {
        // Update preview
        if (mFile.getMimetype().startsWith("image/")) {
          BitmapLoader bl = new BitmapLoader();
          bl.execute(new String[] {mFile.getStoragePath()});
        }

        setButtonsForDown();

      } else {
        setButtonsForRemote();
      }
    }
  }
  @Override
  protected RemoteOperationResult run(WebdavClient client) {
    RemoteOperationResult result = null;

    // code before in FileSyncAdapter.fetchData
    PropFindMethod query = null;
    try {
      Log.d(TAG, "Synchronizing " + mAccount.name + ", fetching files in " + mRemotePath);

      // remote request
      query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
      int status = client.executeMethod(query);

      // check and process response   - /// TODO take into account all the possible status per
      // child-resource
      if (isMultiStatus(status)) {
        MultiStatus resp = query.getResponseBodyAsMultiStatus();

        // synchronize properties of the parent folder, if necessary
        if (mParentId == DataStorageManager.ROOT_PARENT_ID) {
          WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getBaseUri().getPath());
          OCFile parent = fillOCFile(we);
          parent.setParentId(mParentId);
          mStorageManager.saveFile(parent);
          mParentId = parent.getFileId();
        }

        // read contents in folder
        List<OCFile> updatedFiles = new Vector<OCFile>(resp.getResponses().length - 1);
        for (int i = 1; i < resp.getResponses().length; ++i) {
          WebdavEntry we = new WebdavEntry(resp.getResponses()[i], client.getBaseUri().getPath());
          OCFile file = fillOCFile(we);
          file.setParentId(mParentId);
          OCFile oldFile = mStorageManager.getFileByPath(file.getRemotePath());
          if (oldFile != null) {
            if (oldFile.keepInSync()
                && file.getModificationTimestamp() > oldFile.getModificationTimestamp()) {
              disableObservance(
                  file); // first disable observer so we won't get file upload right after download
              requestContentDownload(file);
            }
            file.setKeepInSync(oldFile.keepInSync());
          }

          updatedFiles.add(file);
        }

        // save updated contents in local database; all at once, trying to get a best performance in
        // database update (not a big deal, indeed)
        mStorageManager.saveFiles(updatedFiles);

        // removal of obsolete files
        mChildren = mStorageManager.getDirectoryContent(mStorageManager.getFileById(mParentId));
        OCFile file;
        String currentSavePath = FileDownloader.getSavePath(mAccount.name);
        for (int i = 0; i < mChildren.size(); ) {
          file = mChildren.get(i);
          if (file.getLastSyncDate() != mCurrentSyncTime) {
            Log.d(TAG, "removing file: " + file);
            mStorageManager.removeFile(
                file, (file.isDown() && file.getStoragePath().startsWith(currentSavePath)));
            mChildren.remove(i);
          } else {
            i++;
          }
        }

      } else {
        client.exhaustResponse(query.getResponseBodyAsStream());
      }

      // prepare result object
      result = new RemoteOperationResult(isMultiStatus(status), status);
      Log.i(
          TAG,
          "Synchronizing "
              + mAccount.name
              + ", folder "
              + mRemotePath
              + ": "
              + result.getLogMessage());

    } catch (Exception e) {
      result = new RemoteOperationResult(e);
      Log.e(
          TAG,
          "Synchronizing "
              + mAccount.name
              + ", folder "
              + mRemotePath
              + ": "
              + result.getLogMessage(),
          result.getException());

    } finally {
      if (query != null)
        query.releaseConnection(); // let the connection available for other methods
    }

    return result;
  }