+       
+    protected int downloadFile(WebdavClient client, File targetFile) throws HttpException, IOException, OperationCancelledException {
+        int status = -1;
+        boolean savedFile = false;
+        mGet = new GetMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemoteFile.getRemotePath()));
+        Iterator<OnDatatransferProgressListener> it = null;
+        
+        FileOutputStream fos = null;
+        try {
+            status = client.executeMethod(mGet);
+            if (isSuccess(status)) {
+                targetFile.createNewFile();
+                BufferedInputStream bis = new BufferedInputStream(mGet.getResponseBodyAsStream());
+                fos = new FileOutputStream(targetFile);
+                long transferred = 0;
+
+                byte[] bytes = new byte[4096];
+                int readResult = 0;
+                while ((readResult = bis.read(bytes)) != -1) {
+                    synchronized(mCancellationRequested) {
+                        if (mCancellationRequested.get()) {
+                            mGet.abort();
+                            throw new OperationCancelledException();
+                        }
+                    }
+                    fos.write(bytes, 0, readResult);
+                    transferred += readResult;
+                    synchronized (mDataTransferListeners) {
+                        it = mDataTransferListeners.iterator();
+                        while (it.hasNext()) {
+                            it.next().onTransferProgress(readResult, transferred, mRemoteFile.getLength(), targetFile.getName());
+                        }
+                    }
+                }
+                savedFile = true;
+                Header modificationTime = mGet.getResponseHeader("Last-Modified");
+                if (modificationTime != null) {
+                    Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue());
+                    mModificationTimestamp = (d != null) ? d.getTime() : 0;
+                }
+                
+            } else {
+                client.exhaustResponse(mGet.getResponseBodyAsStream());
+            }
+                
+        } finally {
+            if (fos != null) fos.close();
+            if (!savedFile && targetFile.exists()) {
+                targetFile.delete();
+            }
+            mGet.releaseConnection();    // let the connection available for other methods
+        }
+        return status;
+    }
+    
+    private boolean isSuccess(int status) {
+        return (status == HttpStatus.SC_OK);
+    }
+    
+    private String getTmpPath() {
+        return mTemporalFolder + mRemoteFile.getRemotePath();
+    }
+    
+    public void addDatatransferProgressListener (OnDatatransferProgressListener listener) {
+        synchronized (mDataTransferListeners) {
+            mDataTransferListeners.add(listener);
+        }
+    }
+    
+    public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
+        synchronized (mDataTransferListeners) {
+            mDataTransferListeners.remove(listener);
+        }
+    }
+    
+    public void cancel() {
+        mCancellationRequested.set(true);   // atomic set; there is no need of synchronizing it
+    }