@Override
  public void removeFile(OCFile file, boolean removeLocalCopy) {
    Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, "" + file.getFileId());
    if (getContentProvider() != null) {
      try {
        getContentProvider()
            .delete(
                file_uri,
                ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
                new String[] {mAccount.name});
      } catch (RemoteException e) {
        e.printStackTrace();
      }
    } else {
      getContentResolver()
          .delete(
              file_uri, ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", new String[] {mAccount.name});
    }
    if (file.isDown() && removeLocalCopy) {
      new File(file.getStoragePath()).delete();
    }
    if (file.isDirectory() && removeLocalCopy) {
      File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
      if (f.exists() && f.isDirectory() && (f.list() == null || f.list().length == 0)) {
        f.delete();
      }
    }

    if (file.getFileLength() > 0) {
      updateSizesToTheRoot(file.getParentId());
    }
  }
  @Override
  public void removeDirectory(OCFile dir, boolean removeDBData, boolean removeLocalContent) {
    // TODO consider possible failures
    if (dir != null && dir.isDirectory() && dir.getFileId() != -1) {
      Vector<OCFile> children = getDirectoryContent(dir);
      if (children.size() > 0) {
        OCFile child = null;
        for (int i = 0; i < children.size(); i++) {
          child = children.get(i);
          if (child.isDirectory()) {
            removeDirectory(child, removeDBData, removeLocalContent);
          } else {
            if (removeDBData) {
              removeFile(child, removeLocalContent);
            } else if (removeLocalContent) {
              if (child.isDown()) {
                new File(child.getStoragePath()).delete();
              }
            }
          }
        }
      }
      if (removeDBData) {
        removeFile(dir, true);
      }

      if (dir.getFileLength() > 0) {
        updateSizesToTheRoot(dir.getParentId());
      }
    }
  }
  @Override
  public boolean saveFile(OCFile file) {
    boolean overriden = false;
    ContentValues cv = new ContentValues();
    cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
    cv.put(
        ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
        file.getModificationTimestampAtLastSyncForData());
    cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
    cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
    cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
    if (file.getParentId() != 0) cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
    cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
    if (!file.isDirectory()) cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
    cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
    cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
    cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
    cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);

    boolean sameRemotePath = fileExists(file.getRemotePath());
    boolean changesSizeOfAncestors = false;
    if (sameRemotePath
        || fileExists(file.getFileId())) { // for renamed files; no more delete and create

      OCFile oldFile = null;
      if (sameRemotePath) {
        oldFile = getFileByPath(file.getRemotePath());
        file.setFileId(oldFile.getFileId());
      } else {
        oldFile = getFileById(file.getFileId());
      }
      changesSizeOfAncestors = (oldFile.getFileLength() != file.getFileLength());

      overriden = true;
      if (getContentResolver() != null) {
        getContentResolver()
            .update(
                ProviderTableMeta.CONTENT_URI,
                cv,
                ProviderTableMeta._ID + "=?",
                new String[] {String.valueOf(file.getFileId())});
      } else {
        try {
          getContentProvider()
              .update(
                  ProviderTableMeta.CONTENT_URI,
                  cv,
                  ProviderTableMeta._ID + "=?",
                  new String[] {String.valueOf(file.getFileId())});
        } catch (RemoteException e) {
          Log_OC.e(TAG, "Fail to insert insert file to database " + e.getMessage());
        }
      }
    } else {
      changesSizeOfAncestors = true;
      Uri result_uri = null;
      if (getContentResolver() != null) {
        result_uri = getContentResolver().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
      } else {
        try {
          result_uri = getContentProvider().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
        } catch (RemoteException e) {
          Log_OC.e(TAG, "Fail to insert insert file to database " + e.getMessage());
        }
      }
      if (result_uri != null) {
        long new_id = Long.parseLong(result_uri.getPathSegments().get(1));
        file.setFileId(new_id);
      }
    }

    if (file.isDirectory()) {
      calculateFolderSize(file.getFileId());
      if (file.needsUpdatingWhileSaving()) {
        for (OCFile f : getDirectoryContent(file)) saveFile(f);
      }
    }

    if (changesSizeOfAncestors || file.isDirectory()) {
      updateSizesToTheRoot(file.getParentId());
    }

    return overriden;
  }