diff -ru --strip-trailing-cr BitcasaDLL-20131228/BitcasaDLL/BitcasaAPI.cpp BitcasaDLL-20131230/BitcasaDLL/BitcasaAPI.cpp
--- BitcasaDLL-20131228/BitcasaDLL/BitcasaAPI.cpp	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/BitcasaDLL/BitcasaAPI.cpp	2013-12-31 11:19:02.000000000 +0900
@@ -436,7 +436,7 @@
 
 //File Operations
 // Upload File
-bool BitcasaAPI::UploadFile(std::string encoded_path, std::wstring infilename)
+bool BitcasaAPI::UploadFile(std::string encoded_path, std::wstring infilename, void(*callback)(INT64))
 {
 	if (encoded_path.empty()) encoded_path = "/";
 	if (encoded_path[0] != '/') encoded_path = "/" + encoded_path;
@@ -449,7 +449,7 @@
 	bitcasa.request.query["access_token"] = WideChartoUTF8(access_token);
 	std::map<std::string, std::string> formdata;
 
-	if (bitcasa.POSTfile(URI, formdata, infilename) != 0){
+	if (bitcasa.POSTfile(URI, formdata, infilename, callback) != 0){
 		std::cerr << "\nUploadFile failed" << std::endl;
 		return false;
 	}
@@ -467,7 +467,7 @@
 
 //File Operations
 // Download/Stream File
-bool BitcasaAPI::DownloadFile(std::string encoded_file_id, std::wstring filename, void(*callback)(INT64 trans))
+bool BitcasaAPI::DownloadFile(std::string encoded_file_id, std::wstring filename, INT64 wantSize, void(*callback)(INT64 trans))
 {
 	if (encoded_file_id.empty() || (encoded_file_id.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_=") != std::string::npos)){
 		std::cerr << "Invalid File id" << std::endl;
@@ -487,14 +487,20 @@
 	std::wcerr << "download.";
 	const int transbytes = 64 * 1024 * 1024;
 	INT64 offset = 0;
+	int retrycount = 100;
 	while (true){
 		if (callback) callback(offset);
 		bitcasa.Clear();
 		bitcasa.request.query["access_token"] = WideChartoUTF8(access_token);
-		bitcasa.AddHeader("Range", dynamic_cast<std::stringstream &>(std::stringstream() << "bytes=" << offset << "-" << offset + transbytes).str());
+		bitcasa.AddHeader("Range", dynamic_cast<std::stringstream &>(std::stringstream() << "bytes=" << offset << "-" << (offset + transbytes - 1)).str());
 		bitcasa.GET(URI);
 
 		std::wcerr << ".";
+		if (bitcasa.response.code == 503){
+			Sleep(1000*10);
+			if (--retrycount > 0)
+				continue;
+		}
 		if ((bitcasa.response.code != 200) && (bitcasa.response.code != 206)) {
 			std::wcerr << std::endl;
 			std::cerr << "DownloadFile failed" << std::endl;
@@ -504,13 +510,27 @@
 		INT64 ContentLength = -1;
 		auto it_length = bitcasa.response.header.find("Content-Length");
 		std::stringstream((it_length != bitcasa.response.header.end()) ? it_length->second : "") >> ContentLength;
+		if (bitcasa.response.code == 200){
+			out.seekp(0, std::ios::beg);
+			out.write(&bitcasa.response.body[0], bitcasa.response.body.size());
+			offset = ContentLength;
+			if ((wantSize >= 0) && (offset != wantSize))
+				return false;
+			break;
+		}
+		out.seekp(offset, std::ios::beg);
 		out.write(&bitcasa.response.body[0], bitcasa.response.body.size());
 		if (ContentLength < transbytes){
+			if ((wantSize >= 0) && (offset+ContentLength != wantSize)){
+				continue;
+			}
 			offset += ContentLength;
 			break;
 		}
 		offset += transbytes;
 	}
+	if ((wantSize >= 0) && (offset != wantSize))
+		return false;
 	if (callback) callback(offset);
 	std::wcerr << "done" << std::endl;
 	return true;
diff -ru --strip-trailing-cr BitcasaDLL-20131228/BitcasaDLL/BitcasaAPI.h BitcasaDLL-20131230/BitcasaDLL/BitcasaAPI.h
--- BitcasaDLL-20131228/BitcasaDLL/BitcasaAPI.h	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/BitcasaDLL/BitcasaAPI.h	2013-12-31 11:19:02.000000000 +0900
@@ -42,13 +42,13 @@
 	}
 
 	///////////////////////////////////////
-	bool UploadFile(std::string encoded_path, std::wstring infilename);
+	bool UploadFile(std::string encoded_path, std::wstring infilename, void(*callback)(INT64) = NULL);
 	inline bool UploadFile(std::wstring encoded_path, std::wstring infilename){
 		return UploadFile(WideChartoUTF8(encoded_path), infilename);
 	}
-	bool DownloadFile(std::string encoded_file_id, std::wstring filename, void(*callback)(INT64 trans) = NULL);
-	inline bool DownloadFile(const std::wstring &encoded_file_id, const std::wstring &filename){
-		return DownloadFile(WideChartoUTF8(encoded_file_id), filename);
+	bool DownloadFile(std::string encoded_file_id, std::wstring filename, INT64 wantSize = -1,void(*callback)(INT64 trans) = NULL);
+	inline bool DownloadFile(const std::wstring &encoded_file_id, const std::wstring &filename, INT64 wantSize = -1){
+		return DownloadFile(WideChartoUTF8(encoded_file_id), filename, wantSize);
 	}
 	bool _DeleteFile(std::string encoded_path);
 	inline bool _DeleteFile(const std::wstring &encoded_path){
diff -ru --strip-trailing-cr BitcasaDLL-20131228/BitcasaDLL/BitcasaWrapper.cpp BitcasaDLL-20131230/BitcasaDLL/BitcasaWrapper.cpp
--- BitcasaDLL-20131228/BitcasaDLL/BitcasaWrapper.cpp	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/BitcasaDLL/BitcasaWrapper.cpp	2013-12-31 11:19:02.000000000 +0900
@@ -135,15 +135,20 @@
 {
 	return obj->UploadFile(SystemStringToStdString(encoded_path), SystemStringToStdWString(infilename));
 }
+bool BitcasaWrapper::UploadFile(System::String^ encoded_path, System::String^ infilename, filetrans^ callback)
+{
+	IntPtr delegatePointer = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(callback);
+	return obj->UploadFile(SystemStringToStdString(encoded_path), SystemStringToStdWString(infilename), (void(*)(INT64))delegatePointer.ToPointer());
+}
 
-bool BitcasaWrapper::DownloadFile(System::String^ encoded_file_id, System::String^ filename)
+bool BitcasaWrapper::DownloadFile(System::String^ encoded_file_id, System::String^ filename, Int64 filesize)
 {
-	return obj->DownloadFile(SystemStringToStdString(encoded_file_id), SystemStringToStdWString(filename));
+	return obj->DownloadFile(SystemStringToStdString(encoded_file_id), SystemStringToStdWString(filename), filesize);
 }
-bool BitcasaWrapper::DownloadFile(System::String^ encoded_file_id, System::String^ filename, filetrans^ callback)
+bool BitcasaWrapper::DownloadFile(System::String^ encoded_file_id, System::String^ filename, Int64 filesize, filetrans^ callback)
 {
 	IntPtr delegatePointer = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(callback);
-	return obj->DownloadFile(SystemStringToStdString(encoded_file_id), SystemStringToStdWString(filename), (void(*)(INT64))delegatePointer.ToPointer());
+	return obj->DownloadFile(SystemStringToStdString(encoded_file_id), SystemStringToStdWString(filename), filesize, (void(*)(INT64))delegatePointer.ToPointer());
 }
 
 bool BitcasaWrapper::_DeleteFile(System::String^ encoded_path)
diff -ru --strip-trailing-cr BitcasaDLL-20131228/BitcasaDLL/BitcasaWrapper.h BitcasaDLL-20131230/BitcasaDLL/BitcasaWrapper.h
--- BitcasaDLL-20131228/BitcasaDLL/BitcasaWrapper.h	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/BitcasaDLL/BitcasaWrapper.h	2013-12-31 11:19:02.000000000 +0900
@@ -45,8 +45,9 @@
 		bool MoveFolder(System::String^ encoded_path_old, System::String^ encoded_path_new, System::String^ newfoldername);
 		//////////////////////////////////////
 		bool UploadFile(System::String^ encoded_path, System::String^ infilename);
-		bool DownloadFile(System::String^ encoded_file_id, System::String^ filename);
-		bool DownloadFile(System::String^ encoded_file_id, System::String^ filename, filetrans^ callback);
+		bool UploadFile(System::String^ encoded_path, System::String^ infilename, filetrans^ callback);
+		bool DownloadFile(System::String^ encoded_file_id, System::String^ filename, Int64 filesize);
+		bool DownloadFile(System::String^ encoded_file_id, System::String^ filename, Int64 filesize, filetrans^ callback);
 		bool _DeleteFile(System::String^ encoded_path);
 		bool RenameFile(System::String^ encoded_path_old, System::String^ newfoldername);
 		bool CopyFile(System::String^ encoded_path_old, System::String^ encoded_path_new, System::String^ newfilename);
diff -ru --strip-trailing-cr BitcasaDLL-20131228/BitcasaDLL/http_client.cpp BitcasaDLL-20131230/BitcasaDLL/http_client.cpp
--- BitcasaDLL-20131228/BitcasaDLL/http_client.cpp	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/BitcasaDLL/http_client.cpp	2013-12-31 11:19:02.000000000 +0900
@@ -185,7 +185,7 @@
 	return 1;
 }
 
-int HttpsClient::sendfile(std::ifstream& infile, std::string filename)
+int HttpsClient::sendfile(std::ifstream& infile, std::string filename, void (*callback)(INT64))
 {
 	// get filesize
 	infile.seekg(0, std::fstream::end);
@@ -195,6 +195,7 @@
 	auto begPos = infile.tellg();
 	INT64 filesize = endPos - begPos;
 
+	if (callback) callback(-1);
 
 	/* Send the request */
 	char bchars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
@@ -224,29 +225,35 @@
 	AddHeader("Expect", "100-continue");
 	AddHeader("Content-Type", ("multipart/form-data; boundary=" + boundary));
 
+	int retry = 5;
+	for (; retry > 0; retry--){
+		if (callback) callback(-retry);
+		BIO_puts(bio, request.line.c_str());
+		for (auto it = request.header.begin(); it != request.header.end(); ++it){
+			BIO_puts(bio, (it->first + ": " + it->second + "\r\n").c_str());
+		}
+		BIO_puts(bio, "\r\n");
+		BIO_flush(bio);
 
-	BIO_puts(bio, request.line.c_str());
-	for (auto it = request.header.begin(); it != request.header.end(); ++it){
-		BIO_puts(bio, (it->first + ": " + it->second + "\r\n").c_str());
-	}
-	BIO_puts(bio, "\r\n");
-	BIO_flush(bio);
-
-	/* Read in the response */
-	response.line = ReadLine();
-	//012345678901234
-	//HTTP/1.1 200 OK
-	if (response.line.empty()) {
-		BIO_reset(bio);
-		return 1;
-	}
-	std::stringstream(response.line.substr(9, 3)) >> response.code;
-	response.reason = response.line.substr(13);
+		/* Read in the response */
+		response.line = ReadLine();
+		//012345678901234
+		//HTTP/1.1 200 OK
+		if (response.line.empty()) {
+			BIO_reset(bio);
+			continue;
+		}
+		std::stringstream(response.line.substr(9, 3)) >> response.code;
+		response.reason = response.line.substr(13);
 
-	// 100
-	if (response.code != 100){
-		return 1;
+		// 100
+		if (response.code != 100){
+			BIO_reset(bio);
+			continue;
+		}
+		break;
 	}
+	if (retry == 0) return 1;
 	response.line = ReadLine();
 
 	// send body part
@@ -256,6 +263,7 @@
 	const INT64 bufsize = 32 * 1024 * 1024;
 	while (filesize > 0)
 	{
+		if (callback) callback(filesize);
 		if (filesize > bufsize){
 			sendbuf.resize(bufsize);
 		}
@@ -263,10 +271,12 @@
 			sendbuf.resize(filesize);
 		}
 		infile.read(&sendbuf[0], sendbuf.size());
-		BIO_write(bio, &sendbuf[0], sendbuf.size());
+		if (BIO_write(bio, &sendbuf[0], sendbuf.size()) != sendbuf.size())
+			return 1;
 		filesize -= sendbuf.size();
 		std::cerr << '.';
 	}
+	if (callback) callback(-2);
 	str = postbody.str();
 	BIO_write(bio, str.c_str(), str.size());
 	BIO_flush(bio);
@@ -368,17 +378,17 @@
 	return 0;
 }
 
-int HttpsClient::POSTfile(std::string URI, std::map<std::string, std::string> formdata, std::wstring filename)
+int HttpsClient::POSTfile(std::string URI, std::map<std::string, std::string> formdata, std::wstring filename, void(*callback)(INT64))
 {
 	std::string body = CreateQueryURI(formdata);
 	URI += CreateQueryURI(request.query);
 	request.line = "POST " + URI + " HTTP/1.1\r\n";
 	request.URI = URI;
-	
+
 	std::ifstream infile(filename, std::ios::in | std::ios::binary);
 	if (!infile) return 1;
 	auto ppos = filename.find_last_of(L"\\");
-	sendfile(infile, WideChartoUTF8((ppos == std::string::npos)?filename:filename.substr(ppos+1)));
+	sendfile(infile, WideChartoUTF8((ppos == std::string::npos) ? filename : filename.substr(ppos + 1)), callback);
 	return 0;
 }
 
diff -ru --strip-trailing-cr BitcasaDLL-20131228/BitcasaDLL/http_client.h BitcasaDLL-20131230/BitcasaDLL/http_client.h
--- BitcasaDLL-20131228/BitcasaDLL/http_client.h	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/BitcasaDLL/http_client.h	2013-12-31 11:19:02.000000000 +0900
@@ -17,7 +17,7 @@
 	BIO *cbio;
 
 	int send();
-	int sendfile(std::ifstream& infile, std::string filename);
+	int sendfile(std::ifstream& infile, std::string filename, void(*callback)(INT64) = NULL);
 	std::string ReadLine();
 
 public:
@@ -43,7 +43,7 @@
 	int GET(std::string URI);
 	int POST(std::string URI);
 	int POST(std::string URI, std::map<std::string,std::string> formdata);
-	int POSTfile(std::string URI, std::map<std::string, std::string> formdata, std::wstring filename);
+	int POSTfile(std::string URI, std::map<std::string, std::string> formdata, std::wstring filename, void(*callback)(INT64) = NULL);
 	int _DELETE(std::string URI);
 	int _DELETE(std::string URI, std::map<std::string, std::string> formdata);
 
diff -ru --strip-trailing-cr BitcasaDLL-20131228/bitcasaViewer/BitcasaServer.cs BitcasaDLL-20131230/bitcasaViewer/BitcasaServer.cs
--- BitcasaDLL-20131228/bitcasaViewer/BitcasaServer.cs	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/bitcasaViewer/BitcasaServer.cs	2013-12-31 11:19:02.000000000 +0900
@@ -4,6 +4,7 @@
 using System.Text;
 using System.Threading.Tasks;
 using System.Collections;
+using System.Windows.Forms;
 using BitcasaDLL;
 
 namespace bitcasaViewer
@@ -22,61 +23,73 @@
 
         public FileInfo reloadDir(string fullpath, delegateProgressBar callback)
         {
-            fullpath = fullpath.TrimEnd('\\');
-            FileInfo.dirLoaded[fullpath] = false;
-            return loadDir(fullpath, callback);
+            lock (typeof(FileInfo))
+            {
+                fullpath = fullpath.TrimEnd('\\');
+                FileInfo.dirLoaded[fullpath] = false;
+                return loadDir(fullpath, callback);
+            }
         }
 
         public FileInfo loadDir(string fullpath, delegateProgressBar callback)
         {
-            fullpath = fullpath.TrimEnd('\\');
-            var dirItem = FileInfo.dirTree[fullpath];
-            if (!FileInfo.dirLoaded[fullpath])
+            lock (typeof(FileInfo))
             {
-                if (callback != null) callback(50);
-                var result = bitcasa.ListFolder(dirItem.path);
-                if (callback != null) callback(75);
-                FileInfo.dirLoaded[fullpath] = true;
-                var root = result["result"]["items"];
-                for (ulong i = 0; i < root.size; i++)
-                {
-                    var item = root.Items(i);
-                    FileInfo.GetItem((item as json_objectWrapper), "");
+                fullpath = fullpath.TrimEnd('\\');
+                var dirItem = FileInfo.dirTree[fullpath];
+                if (!FileInfo.dirLoaded[fullpath])
+                {
+                    if (callback != null) callback(50);
+                    var result = bitcasa.ListFolder(dirItem.path);
+                    if (callback != null) callback(75);
+                    FileInfo.dirLoaded[fullpath] = true;
+                    var root = result["result"]["items"];
+                    for (ulong i = 0; i < root.size; i++)
+                    {
+                        var item = root.Items(i);
+                        FileInfo.GetItem((item as json_objectWrapper), "");
+                    }
                 }
+                if (callback != null) callback(100);
+                return dirItem;
             }
-            if (callback != null) callback(100);
-            return dirItem;
         }
 
         public void loadALL(delegateProgressBar callback)
         {
-            FileInfo.clearDictionary();
-            if (callback != null) callback(25);
-            var result = bitcasa.ListFolder("/", true);
-            var root = result["result"]["items"];
-            if (callback != null) callback(75);
-            FileInfo.dirLoaded[""] = true;
-            FileInfo.dirLoaded["\\"] = true;
-            for (ulong i = 0; i < root.size; i++)
-            {
-                var item = root.Items(i);
-                var path = FileInfo.GetItem((item as json_objectWrapper), "").fullpath;
-                FileInfo.dirLoaded[path] = true;
+            lock (typeof(FileInfo))
+            {
+                FileInfo.clearDictionary();
+                if (callback != null) callback(25);
+                var result = bitcasa.ListFolder("/", true);
+                var root = result["result"]["items"];
+                if (callback != null) callback(75);
+                FileInfo.dirLoaded[""] = true;
+                FileInfo.dirLoaded["\\"] = true;
+                for (ulong i = 0; i < root.size; i++)
+                {
+                    var item = root.Items(i);
+                    var path = FileInfo.GetItem((item as json_objectWrapper), "").fullpath;
+                    FileInfo.dirLoaded[path] = true;
+                }
+                loadall_flag = true;
+                if (callback != null) callback(100);
             }
-            loadall_flag = true;
-            if (callback != null) callback(100);
         }
 
         public FileInfo[] listChild(string parentpath)
         {
-            ArrayList result = new ArrayList();
-            foreach(var item in FileInfo.dirTree.SkipWhile(x=>!x.Key.StartsWith(parentpath)).TakeWhile(x=>x.Key.StartsWith(parentpath)))
+            lock (typeof(FileInfo))
             {
-                if ((item.Key != parentpath) && (item.Key.Substring(parentpath.Length+1).IndexOf('\\') < 0))
-                    result.Add(item.Value);
-            }
+                ArrayList result = new ArrayList();
+                foreach (var item in FileInfo.dirTree.SkipWhile(x => !x.Key.StartsWith(parentpath)).TakeWhile(x => x.Key.StartsWith(parentpath)))
+                {
+                    if ((item.Key != parentpath) && (item.Key.Substring(parentpath.Length + 1).IndexOf('\\') < 0))
+                        result.Add(item.Value);
+                }
 
-            return (FileInfo [])result.ToArray(typeof(FileInfo));
+                return (FileInfo[])result.ToArray(typeof(FileInfo));
+            }
         }
 
         public bool download(FileInfo target, string localfilename, delegateProgressBar callback)
@@ -84,11 +97,14 @@
             if (target.id == "") return false;
             return bitcasa.DownloadFile(
                 target.id, 
-                localfilename, 
+                localfilename,
+                target.size,
                 new filetrans(
                     (Int64 pos)=>{
                         if (callback != null)
-                            callback((int)(pos / target.size));
+                        {
+                            callback((int)(100.0 * pos / target.size));
+                        }
                     })
                 );
         }
@@ -97,10 +113,21 @@
         {
             if(callback != null) callback(0);
             if (targetdir.path == "") return false;
-            if(callback != null) callback(50);
-            var ret = bitcasa.UploadFile(targetdir.path, localfilename);
-            if(callback != null) callback(100);
-            return ret;
+            Int64 filesize = 1;
+            return bitcasa.UploadFile(
+                targetdir.path, 
+                localfilename,
+                new filetrans(
+                    (Int64 pos) =>
+                    {
+                        if (callback != null)
+                        {
+                            if ((pos >= 0) && (filesize < pos)) filesize = pos;
+                            if (pos < 0) callback((int)pos);
+                            else callback((int)(100.0 * (filesize-pos) / filesize));
+                        }
+                    })
+                );
         }
 
         public bool rename(FileInfo target, string newname, delegateProgressBar callback)
@@ -117,7 +144,10 @@
             {
                 ret = bitcasa.RenameFile(target.path, newname);
             }
-            FileInfo.dirTree.Remove(target.fullpath);
+            lock (typeof(FileInfo))
+            {
+                FileInfo.dirTree.Remove(target.fullpath);
+            }
             if(callback != null) callback(50);
             reloadDir(FileInfo.pathtoparent(target.path), null);
             if (callback != null) callback(100);
@@ -139,7 +169,10 @@
                 {
                     ret = bitcasa.MoveFile(oldpath.path, newpath.path, oldpath.name);
                 }
-                FileInfo.dirTree.Remove(oldpath.fullpath);
+                lock (typeof(FileInfo))
+                {
+                    FileInfo.dirTree.Remove(oldpath.fullpath);
+                }
                 if (!ret) break;
                 if (callback != null) callback(progress+=(50/oldpaths.Length));
             }
@@ -164,7 +197,10 @@
                 {
                     ret = bitcasa.CopyFile(oldpath.path, newpath.path, oldpath.name);
                 }
-                FileInfo.dirTree.Remove(oldpath.fullpath);
+                lock (typeof(FileInfo))
+                {
+                    FileInfo.dirTree.Remove(oldpath.fullpath);
+                }
                 if (!ret) break;
                 if (callback != null) callback(progress += (50 / oldpaths.Length));
             }
@@ -182,7 +218,10 @@
             if (callback != null) callback(25);
             ret = bitcasa.AddFolder(targetdir.path, newname);
             if (callback != null) callback(50);
-            reloadDir(FileInfo.pathtoparent(targetdir.path), null);
+            lock (typeof(FileInfo))
+            {
+                reloadDir(FileInfo.pathtoparent(targetdir.path), null);
+            }
             if (callback != null) callback(100);
             return ret;
         }
@@ -201,7 +240,10 @@
                 {
                     ret = bitcasa._DeleteFile(target.path);
                 }
-                FileInfo.dirTree.Remove(target.fullpath);
+                lock (typeof(FileInfo))
+                {
+                    FileInfo.dirTree.Remove(target.fullpath);
+                }
                 if (!ret) break;
                 if (callback != null) callback(progress += (50 / targets.Length));
             }
diff -ru --strip-trailing-cr BitcasaDLL-20131228/bitcasaViewer/bitcasaViewer.csproj BitcasaDLL-20131230/bitcasaViewer/bitcasaViewer.csproj
--- BitcasaDLL-20131228/bitcasaViewer/bitcasaViewer.csproj	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/bitcasaViewer/bitcasaViewer.csproj	2013-12-31 11:19:02.000000000 +0900
@@ -52,7 +52,8 @@
     <Prefer32Bit>true</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BitcasaDLL">
+    <Reference Include="BitcasaDLL, Version=1.0.5112.22492, Culture=neutral, processorArchitecture=AMD64">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\x64\Release\BitcasaDLL.dll</HintPath>
     </Reference>
     <Reference Include="System" />
@@ -65,7 +66,8 @@
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml" />
-    <Reference Include="WebWindow">
+    <Reference Include="WebWindow, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\WebWindow\bin\x64\Release\WebWindow.dll</HintPath>
     </Reference>
   </ItemGroup>
@@ -126,6 +128,9 @@
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
+  <ItemGroup>
+    <WCFMetadata Include="Service References\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
diff -ru --strip-trailing-cr BitcasaDLL-20131228/bitcasaViewer/Form1.cs BitcasaDLL-20131230/bitcasaViewer/Form1.cs
--- BitcasaDLL-20131228/bitcasaViewer/Form1.cs	2013-12-31 12:54:52.000000000 +0900
+++ BitcasaDLL-20131230/bitcasaViewer/Form1.cs	2013-12-31 11:19:02.000000000 +0900
@@ -19,7 +19,7 @@
         private ArrayList SelectedFiles = new ArrayList();
         private bool loadall_flag = false;
         private FormFind findform = new FormFind();
-
+        private bool ongoing = false;
 
         public Form1()
         {
@@ -34,8 +34,8 @@
 
         private void listFileItems(FileInfo[] items, bool dotfiles)
         {
-            listView1.Items.Clear();
             listView1.BeginUpdate();
+            listView1.Items.Clear();
             if (dotfiles)
             {
                 string[] selfitem = { ".", "", "", "", "", "" };
@@ -87,43 +87,59 @@
 
         private FileInfo SelectItemToFileinfo()
         {
-            var seletedItem = listView1.SelectedItems[0];
-            var item = FileInfo.dirTree[seletedItem.SubItems[3].Text];
-            if (seletedItem.SubItems[0].Text == ".")
-            {
-                item = FileInfo.dirTree[treeView1.SelectedNode.FullPath.Substring(4)];
-            }
-            if (seletedItem.SubItems[0].Text == "..")
+            lock (typeof(FileInfo))
             {
-                var moveto = treeView1.SelectedNode.Parent;
-                if (moveto != null)
-                    item = FileInfo.dirTree[moveto.FullPath.Substring(4)];
-                else
-                    item = FileInfo.dirTree["\\"];
+                var seletedItem = listView1.SelectedItems[0];
+                var item = FileInfo.dirTree[seletedItem.SubItems[3].Text];
+                if (seletedItem.SubItems[0].Text == ".")
+                {
+                    item = FileInfo.dirTree[treeView1.SelectedNode.FullPath.Substring(4)];
+                }
+                if (seletedItem.SubItems[0].Text == "..")
+                {
+                    var moveto = treeView1.SelectedNode.Parent;
+                    if (moveto != null)
+                        item = FileInfo.dirTree[moveto.FullPath.Substring(4)];
+                    else
+                        item = FileInfo.dirTree["\\"];
+                }
+                return item;
             }
-            return item;
         }
 
         private void reloadview()
         {
             try
             {
-                var Node = treeView1.SelectedNode;
-                if (Node == null) return;
-                var selectItem = Node.FullPath.Substring(4);
-
-                var treeparent = bitcasa.loadDir(selectItem, this.progress);
-                var treeitems = bitcasa.listChild(treeparent.fullpath);
-                Node.Nodes.Clear();
-                foreach (FileInfo items in treeitems)
+                lock (bitcasa)
                 {
-                    Node.Nodes.Add(items.name);
-                }
-                Node.Expand();
+                    if (ongoing)
+                    {
+                        MessageBox.Show("now processing...");
+                        return;
+                    }
+                    var Node = treeView1.SelectedNode;
+                    if (Node == null) return;
+                    var selectItem = Node.FullPath.Substring(4);
+
+                    toolStripStatusLabel1.Text = "loading...";
+                    Update();
+                    var treeparent = bitcasa.loadDir(selectItem, this.progress);
+                    var treeitems = bitcasa.listChild(treeparent.fullpath);
+                    Node.Nodes.Clear();
+                    foreach (FileInfo items in treeitems)
+                    {
+                        Node.Nodes.Add(items.name);
+                    }
+                    Node.Expand();
 
-                listFileItems(treeitems, true);
+                    listFileItems(treeitems, true);
+                }
+            }
+            finally
+            {
+                toolStripStatusLabel1.Text = "";
             }
-            catch { }
         }
 
         private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
@@ -133,24 +149,35 @@
 
         private void loginToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            progress(50);
-            if (!bitcasa.login())
+            try
             {
-                MessageBox.Show("Login failed.");
-                progress(0);
-                return;
+                lock (bitcasa)
+                {
+                    toolStripStatusLabel1.Text = "Login...";
+                    Update();
+                    progress(50);
+                    if (!bitcasa.login())
+                    {
+                        MessageBox.Show("Login failed.");
+                        progress(0);
+                        return;
+                    }
+                    progress(100);
+                    reloadToolStripMenuItem.Enabled = true;
+                    scanAllToolStripMenuItem.Enabled = true;
+                    treeView1.Nodes.Add("root");
+                    loginToolStripMenuItem.Enabled = false;
+                    loginToolStripMenuItem.Text = "done.";
+                }
+            }
+            finally {
+                toolStripStatusLabel1.Text = "";
             }
-            progress(100);
-            reloadToolStripMenuItem.Enabled = true;
-            scanAllToolStripMenuItem.Enabled = true;
-            treeView1.Nodes.Add("root");
-            loginToolStripMenuItem.Enabled = false;
-            loginToolStripMenuItem.Text = "done.";
         }
 
         private void listView1_SelectedIndexChanged(object sender, EventArgs e)
         {
-            try
+            lock (typeof(FileInfo))
             {
                 if (listView1.SelectedItems.Count > 1)
                 {
@@ -158,6 +185,7 @@
                     listBox1.Items.Add(listView1.SelectedItems.Count.ToString() + " items");
                     Int64 sizesum = 0;
                     int dircount = 0;
+                    if (listView1.SelectedItems.Count > 1000) return;
                     foreach (ListViewItem selectitem in listView1.SelectedItems)
                     {
                         var item = FileInfo.dirTree[selectitem.SubItems[3].Text];
@@ -194,7 +222,6 @@
                     detailShowFileItems(item);
                 }
             }
-            catch { }
         }
 
         private void decendTree(string fullpath)
@@ -204,6 +231,7 @@
             {
                 treeView1.SelectedNode = treeView1.Nodes[0];
                 decendTree(fullpath.Substring(1));
+                return;
             }
             var pos = fullpath.IndexOf('\\');
             var target = (pos < 0)? fullpath: fullpath.Substring(0, pos);
@@ -214,53 +242,124 @@
                     treeView1.SelectedNode = tn;
                     if (pos > 0)
                         decendTree(fullpath.Substring(pos + 1));
-                    treeView1.Focus();
                     return;
                 }
             }
             treeView1.SelectedNode.Nodes.Add(target);
             if (pos > 0)
                 decendTree(fullpath.Substring(pos + 1));
-            treeView1.Focus();
         }
 
         private void listView1_DoubleClick(object sender, EventArgs e)
         {
             if (listView1.SelectedItems.Count == 1)
             {
-                var item = listView1.SelectedItems[0].SubItems[0].Text;
-                if (item == ".") return;
-                if (item == "..")
+                lock (typeof(FileInfo))
                 {
-                    var moveto = treeView1.SelectedNode.Parent;
-                    if (moveto != null) treeView1.SelectedNode = moveto;
+                    if (ongoing)
+                    {
+                        MessageBox.Show("now processing...");
+                        return;
+                    }
+                    var item = listView1.SelectedItems[0].SubItems[0].Text;
+                    if (item == ".") return;
+                    if (item == "..")
+                    {
+                        var moveto = treeView1.SelectedNode.Parent;
+                        if (moveto != null) treeView1.SelectedNode = moveto;
+                        treeView1.Focus();
+                        return;
+                    }
+                    var diritem = FileInfo.dirTree[listView1.SelectedItems[0].SubItems[3].Text];
+                    listView1.Items.Clear();
+                    listView1.BeginUpdate();
+                    decendTree(diritem.fullpath);
+                    listView1.EndUpdate();
                     treeView1.Focus();
-                    return;
                 }
-                var diritem = FileInfo.dirTree[listView1.SelectedItems[0].SubItems[3].Text];
-                decendTree(diritem.fullpath);
             }
         }
 
-        private void reloadToolStripMenuItem_Click(object sender, EventArgs e)
+        private async void reloadToolStripMenuItem_Click(object sender, EventArgs e)
         {
+            if (ongoing)
+            {
+                MessageBox.Show("now processing...");
+                return;
+            }
+            toolStripStatusLabel1.Text = "reload...";
+            Update();
             var selectItem = treeView1.SelectedNode.FullPath.Substring(4);
-            bitcasa.reloadDir(selectItem, this.progress);
+            toolStripProgressBar1.Style = ProgressBarStyle.Marquee;
+            ongoing = true;
+            await Task.Run(
+                () =>
+                {
+                    lock (bitcasa)
+                    {
+                        bitcasa.reloadDir(
+                            selectItem,
+                            (int p) => this.BeginInvoke(
+                                (BitcasaServer.delegateProgressBar)(
+                                            (int x) =>
+                                            {
+                                                progress(x);
+                                            }),
+                                        new object[] { p }
+                            )
+                        );
+                    }
+                });
+            ongoing = false;
+            toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
             reloadview();
+            toolStripStatusLabel1.Text = "";
         }
 
-        private void scanAllToolStripMenuItem_Click(object sender, EventArgs e)
+        private async void scanAllToolStripMenuItem_Click(object sender, EventArgs e)
         {
+            if (ongoing)
+            {
+                MessageBox.Show("now processing...");
+                return;
+            }
             if (loadall_flag)
             {
                 FindFiles();
                 return;
             }
-
-            bitcasa.loadALL(this.progress);
+            toolStripStatusLabel1.Text = "search all subfolders...";
+            Update();
+            toolStripProgressBar1.Style = ProgressBarStyle.Marquee;
+            ongoing = true;
+            listView1.Enabled = false;
+            treeView1.Enabled = false;
+            await Task.Run(
+                () =>
+                {
+                    lock (bitcasa)
+                    {
+                        bitcasa.loadALL(
+                            (int p) => this.BeginInvoke(
+                                (BitcasaServer.delegateProgressBar)(
+                                            (int x) =>
+                                            {
+                                                progress(x);
+                                            }),
+                                        new object[] { p }
+                            )
+                        );
+                    }
+                });
+            ongoing = false;
+            listView1.Enabled = true;
+            treeView1.Enabled = true;
             scanAllToolStripMenuItem.Text = "Find...";
+            Update();
             loadall_flag = true;
             reloadview();
+            toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
+            toolStripStatusLabel1.Text = "";
         }
 
         private bool Timetest(string key)
@@ -283,61 +382,72 @@
         }
         private bool Sizetest(string key)
         {
-            if (findform.sizemin >= 0)
+            lock (typeof(FileInfo))
             {
-                if (findform.sizemin > FileInfo.dirTree[key].size)
+                if (findform.sizemin >= 0)
                 {
-                    return false;
+                    if (findform.sizemin > FileInfo.dirTree[key].size)
+                    {
+                        return false;
+                    }
                 }
-            }
-            if (findform.sizemax >= 0)
-            {
-                if (findform.sizemax < FileInfo.dirTree[key].size)
+                if (findform.sizemax >= 0)
                 {
-                    return false;
+                    if (findform.sizemax < FileInfo.dirTree[key].size)
+                    {
+                        return false;
+                    }
                 }
+                return true;
             }
-            return true;
         }
 
         private void FindFiles()
         {
             if (findform.ShowDialog() == DialogResult.OK)
             {
-                ArrayList hit = new ArrayList();
+                lock (typeof(FileInfo))
+                {
+                    toolStripStatusLabel1.Text = "find...";
+                    Update();
 
-                progress(25);
-                listView1.Items.Clear();
-                if (findform.IsRegular)
-                {
-                    Regex regtest = new Regex(findform.findstr);
-                    foreach (string key in FileInfo.dirTree.Keys)
-                    {
-                        if (!regtest.IsMatch(key))
-                            continue;
-                        if (!Sizetest(key))
-                            continue;
-                        if (!Timetest(key))
-                            continue;
-                        hit.Add(FileInfo.dirTree[key]);
+                    ArrayList hit = new ArrayList();
+                    progress(25);
+                    toolStripProgressBar1.Style = ProgressBarStyle.Marquee;
+                    listView1.Items.Clear();
+                    if (findform.IsRegular)
+                    {
+                        Regex regtest = new Regex(findform.findstr);
+                        foreach (string key in FileInfo.dirTree.Keys)
+                        {
+                            if (!regtest.IsMatch(key))
+                                continue;
+                            if (!Sizetest(key))
+                                continue;
+                            if (!Timetest(key))
+                                continue;
+                            hit.Add(FileInfo.dirTree[key]);
+                        }
                     }
-                }
-                else
-                {
-                    foreach (string key in FileInfo.dirTree.Keys)
+                    else
                     {
-                        if (key.IndexOf(findform.findstr) < 0)
-                            continue;
-                        if (!Sizetest(key))
-                            continue;
-                        if (!Timetest(key))
-                            continue;
-                        hit.Add(FileInfo.dirTree[key]);
+                        foreach (string key in FileInfo.dirTree.Keys)
+                        {
+                            if (key.IndexOf(findform.findstr) < 0)
+                                continue;
+                            if (!Sizetest(key))
+                                continue;
+                            if (!Timetest(key))
+                                continue;
+                            hit.Add(FileInfo.dirTree[key]);
+                        }
                     }
+                    progress(50);
+                    listFileItems((FileInfo[])hit.ToArray(typeof(FileInfo)), false);
+                    progress(100);
+                    toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
+                    toolStripStatusLabel1.Text = "";
                 }
-                progress(50);
-                listFileItems((FileInfo[])hit.ToArray(typeof(FileInfo)), false);
-                progress(100);
             }
         }
 
diff -ru --strip-trailing-cr BitcasaDLL-20131228/bitcasaViewer/Form1.Designer.cs BitcasaDLL-20131230/bitcasaViewer/Form1.Designer.cs
--- BitcasaDLL-20131228/bitcasaViewer/Form1.Designer.cs	2013-12-31 12:54:50.000000000 +0900
+++ BitcasaDLL-20131230/bitcasaViewer/Form1.Designer.cs	2013-12-31 11:19:00.000000000 +0900
@@ -60,6 +60,8 @@
             this.fullpath = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
             this.path = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
             this.id = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+            this.statusStrip2 = new System.Windows.Forms.StatusStrip();
+            this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
             this.listBox1 = new System.Windows.Forms.ListBox();
             this.checkBox_reload = new System.Windows.Forms.CheckBox();
             this.menuStrip1.SuspendLayout();
@@ -74,6 +76,7 @@
             this.splitContainer2.Panel1.SuspendLayout();
             this.splitContainer2.Panel2.SuspendLayout();
             this.splitContainer2.SuspendLayout();
+            this.statusStrip2.SuspendLayout();
             this.SuspendLayout();
             // 
             // menuStrip1
@@ -242,12 +245,11 @@
             // 
             this.toolStripProgressBar1.Name = "toolStripProgressBar1";
             this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16);
+            this.toolStripProgressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
             // 
             // treeView1
             // 
             this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.treeView1.FullRowSelect = true;
-            this.treeView1.HideSelection = false;
             this.treeView1.Location = new System.Drawing.Point(0, 0);
             this.treeView1.Name = "treeView1";
             this.treeView1.Size = new System.Drawing.Size(177, 579);
@@ -267,6 +269,7 @@
             // 
             // splitContainer2.Panel2
             // 
+            this.splitContainer2.Panel2.Controls.Add(this.statusStrip2);
             this.splitContainer2.Panel2.Controls.Add(this.listBox1);
             this.splitContainer2.Size = new System.Drawing.Size(626, 579);
             this.splitContainer2.SplitterDistance = 341;
@@ -323,6 +326,23 @@
             this.id.Text = "file id(encoded)";
             this.id.Width = 87;
             // 
+            // statusStrip2
+            // 
+            this.statusStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.toolStripStatusLabel1});
+            this.statusStrip2.Location = new System.Drawing.Point(0, 212);
+            this.statusStrip2.Name = "statusStrip2";
+            this.statusStrip2.Size = new System.Drawing.Size(626, 22);
+            this.statusStrip2.TabIndex = 6;
+            this.statusStrip2.Text = "statusStrip2";
+            // 
+            // toolStripStatusLabel1
+            // 
+            this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
+            this.toolStripStatusLabel1.Size = new System.Drawing.Size(580, 17);
+            this.toolStripStatusLabel1.Spring = true;
+            this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
             // listBox1
             // 
             this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -368,8 +388,11 @@
             this.statusStrip1.PerformLayout();
             this.splitContainer2.Panel1.ResumeLayout(false);
             this.splitContainer2.Panel2.ResumeLayout(false);
+            this.splitContainer2.Panel2.PerformLayout();
             ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
             this.splitContainer2.ResumeLayout(false);
+            this.statusStrip2.ResumeLayout(false);
+            this.statusStrip2.PerformLayout();
             this.ResumeLayout(false);
             this.PerformLayout();
 
@@ -410,6 +433,8 @@
         private System.Windows.Forms.StatusStrip statusStrip1;
         private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1;
         private System.Windows.Forms.CheckBox checkBox_reload;
+        private System.Windows.Forms.StatusStrip statusStrip2;
+        private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
     }
 }
 
diff -ru --strip-trailing-cr BitcasaDLL-20131228/bitcasaViewer/Form1_popup.cs BitcasaDLL-20131230/bitcasaViewer/Form1_popup.cs
--- BitcasaDLL-20131228/bitcasaViewer/Form1_popup.cs	2013-12-31 12:54:50.000000000 +0900
+++ BitcasaDLL-20131230/bitcasaViewer/Form1_popup.cs	2013-12-31 11:19:00.000000000 +0900
@@ -5,8 +5,10 @@
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Threading;
 using System.Windows.Forms;
 using System.Collections;
+using System.Drawing;
 
 
 namespace bitcasaViewer
@@ -15,6 +17,12 @@
     {
         private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
         {
+            if (ongoing)
+            {
+                MessageBox.Show("now processing...");
+                e.Cancel = true;
+                return;
+            }
             bool folder_flag = false;
             bool file_flag = false;
             downloadToolStripMenuItem.Enabled = false;
@@ -63,52 +71,166 @@
             }
         }
 
-        private void downloadToolStripMenuItem_Click(object sender, EventArgs e)
+        private async void downloadToolStripMenuItem_Click(object sender, EventArgs e)
         {
             if (listView1.SelectedItems.Count == 1)
             {
-                var item = FileInfo.dirTree[listView1.SelectedItems[0].SubItems[3].Text];
+                FileInfo item;
+                lock(typeof(FileInfo))
+                    item = FileInfo.dirTree[listView1.SelectedItems[0].SubItems[3].Text];
                 if (item.id == "") return;
                 saveFileDialog1.FileName = item.name;
                 if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                 {
-                    if (!bitcasa.download(item, saveFileDialog1.FileName, this.progress))
+                    progress(0);
+                    ongoing = true;
+                    toolStripStatusLabel1.Text = "downloading... " + item.name;
+                    var ret = await Task.Run(
+                        () =>
+                        {
+                            lock (bitcasa)
+                            {
+                                return bitcasa.download(
+                                    item,
+                                    saveFileDialog1.FileName,
+                                    (int p) => this.BeginInvoke(
+                                        (BitcasaServer.delegateProgressBar)(
+                                            (int x) =>
+                                            {
+                                                progress(x);
+                                            }),
+                                        new object[] { p }
+                                    )
+                                );
+                            }
+                        });
+
+                    if (ret)
+                    {
+                        progress(100);
+                    }
+                    else
                     {
                         MessageBox.Show("download failed.");
                         progress(0);
                     }
-                    progress(100);
+                    toolStripStatusLabel1.Text = "";
+                    ongoing = false;
                 }
             }
             if (listView1.SelectedItems.Count > 1)
             {
                 if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                 {
-                    foreach (ListViewItem listitem in listView1.SelectedItems)
+                    ArrayList targetitems = new ArrayList();
+                    lock (typeof(FileInfo))
                     {
-                        var item = FileInfo.dirTree[listitem.SubItems[3].Text];
-                        if (item.id == "") continue;
-
-                        if (!bitcasa.download(item, folderBrowserDialog1.SelectedPath + "\\" + item.name, this.progress))
+                        foreach (ListViewItem listitem in listView1.SelectedItems)
                         {
-                            MessageBox.Show("download failed.");
-                            progress(0);
-                            break;
+                            var item = FileInfo.dirTree[listitem.SubItems[3].Text];
+                            if (item.id == "") continue;
+
+                            targetitems.Add(item);
                         }
+                    }
+                    progress(0);
+                    ongoing = true;
+                    var result = await Task.Run(
+                        () =>
+                        {
+                            lock (bitcasa)
+                            {
+                                var path = folderBrowserDialog1.SelectedPath + "\\";
+                                bool ret = true;
+                                foreach (FileInfo item in targetitems)
+                                {
+                                    this.BeginInvoke((MethodInvoker)(() => toolStripStatusLabel1.Text = "downloading... " + item.name));
+                                    ret = bitcasa.download(
+                                        item,
+                                        path + item.name,
+                                        (int p) => this.BeginInvoke(
+                                            (BitcasaServer.delegateProgressBar)(
+                                                (int x) =>
+                                                {
+                                                    progress(x);
+                                                }),
+                                            new object[] { p }
+                                        )
+                                    );
+                                    if (!ret) break;
+                                }
+                                return ret;
+                            }
+                        });
+                    if (result)
+                    {
                         progress(100);
                     }
+                    else
+                    {
+                        MessageBox.Show("download failed.");
+                        progress(0);
+                    }
+                    toolStripStatusLabel1.Text = "";
+                    ongoing = false;
                 }
             }
         }
 
-        private void uploadToolStripMenuItem_Click(object sender, EventArgs e)
+        private async void uploadToolStripMenuItem_Click(object sender, EventArgs e)
         {
             var item = SelectItemToFileinfo();
             if (item.path == "") return;
             if (openFileDialog1.ShowDialog() == DialogResult.OK)
             {
-                if (!bitcasa.upload(item, openFileDialog1.FileName, this.progress))
+                progress(0);
+                ongoing = true;
+                treeView1.Enabled = false;
+                listView1.Enabled = false;
+                var filename = openFileDialog1.FileName;
+                toolStripStatusLabel1.Text = "uploading... " + filename;
+                var ret = await Task.Run(
+                    () =>
+                    {
+                        lock (bitcasa)
+                        {
+                            return bitcasa.upload(
+                                item,
+                                filename,
+                                (int p) => this.BeginInvoke(
+                                    (BitcasaServer.delegateProgressBar)(
+                                        (int x) =>
+                                        {
+                                            if (x < 0)
+                                            {
+                                                toolStripProgressBar1.Style = ProgressBarStyle.Marquee;
+                                            }
+                                            else
+                                            {
+                                                toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
+                                                progress(x);
+                                            }
+                                        }),
+                                    new object[] { p }
+                                )
+                            );
+                        }
+                    });
+
+                toolStripProgressBar1.Style = ProgressBarStyle.Continuous;                            
+                if (ret)
+                {
+                    progress(100);
+                }
+                else
+                {
                     MessageBox.Show("upload not completed(failed or too slow response).");
+                    progress(0);
+                }
+                toolStripStatusLabel1.Text = "";
+                ongoing = false;
+                treeView1.Enabled = true;
+                listView1.Enabled = true;
             }
             if (checkBox_reload.Checked)
                 reloadview();
@@ -126,10 +248,13 @@
                 if (dialog.InputString == item.name) return;
                 if (dialog.InputString == "") return;
 
-                if (!bitcasa.mkDir(item, dialog.InputString, this.progress))
+                lock (bitcasa)
                 {
-                    MessageBox.Show("AddFolder failed.");
-                    return;
+                    if (!bitcasa.mkDir(item, dialog.InputString, this.progress))
+                    {
+                        MessageBox.Show("AddFolder failed.");
+                        return;
+                    }
                 }
             }
             if (checkBox_reload.Checked)
@@ -138,32 +263,41 @@
 
         private void renameToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            var seletedItem = listView1.SelectedItems[0];
-            if ((seletedItem.SubItems[0].Text == ".") || (seletedItem.SubItems[0].Text == "..")) return;
-            var item = FileInfo.dirTree[seletedItem.SubItems[3].Text];
-            var dialog = new FormInput();
-            dialog.LabelText = "enter new name";
-            dialog.InputString = item.name;
-            if (dialog.ShowDialog() == DialogResult.OK)
+            lock (typeof(FileInfo))
             {
-                if (dialog.InputString == item.name) return;
-                if (!bitcasa.rename(item, dialog.InputString, this.progress))
+                var seletedItem = listView1.SelectedItems[0];
+                if ((seletedItem.SubItems[0].Text == ".") || (seletedItem.SubItems[0].Text == "..")) return;
+                var item = FileInfo.dirTree[seletedItem.SubItems[3].Text];
+                var dialog = new FormInput();
+                dialog.LabelText = "enter new name";
+                dialog.InputString = item.name;
+                if (dialog.ShowDialog() == DialogResult.OK)
                 {
-                    MessageBox.Show("Rename failed.");
-                    return;
+                    if (dialog.InputString == item.name) return;
+                    lock (bitcasa)
+                    {
+                        if (!bitcasa.rename(item, dialog.InputString, this.progress))
+                        {
+                            MessageBox.Show("Rename failed.");
+                            return;
+                        }
+                    }
                 }
+                if (checkBox_reload.Checked)
+                    reloadview();
             }
-            if (checkBox_reload.Checked)
-                reloadview();
         }
 
         private void pushSelectedList()
         {
-            foreach (ListViewItem listitem in listView1.SelectedItems)
+            lock (typeof(FileInfo))
             {
-                var item = FileInfo.dirTree[listitem.SubItems[3].Text];
-                if (item.name == "") continue;
-                SelectedFiles.Add(item);
+                foreach (ListViewItem listitem in listView1.SelectedItems)
+                {
+                    var item = FileInfo.dirTree[listitem.SubItems[3].Text];
+                    if (item.name == "") continue;
+                    SelectedFiles.Add(item);
+                }
             }
         }
 
@@ -175,11 +309,14 @@
             }
             else
             {
-                var item = SelectItemToFileinfo();
-                if (item.path == "") return;
-                if (!bitcasa.moveitem((FileInfo[])SelectedFiles.ToArray(typeof(FileInfo)), item, this.progress))
-                    MessageBox.Show("Move failed.");
-                SelectedFiles.Clear();
+                lock (bitcasa)
+                {
+                    var item = SelectItemToFileinfo();
+                    if (item.path == "") return;
+                    if (!bitcasa.moveitem((FileInfo[])SelectedFiles.ToArray(typeof(FileInfo)), item, this.progress))
+                        MessageBox.Show("Move failed.");
+                    SelectedFiles.Clear();
+                }
             }
             if (checkBox_reload.Checked)
                 reloadview();
@@ -193,11 +330,14 @@
             }
             else
             {
-                var item = SelectItemToFileinfo();
-                if (item.path == "") return;
-                if (!bitcasa.copyitem((FileInfo[])SelectedFiles.ToArray(typeof(FileInfo)), item, this.progress))
-                    MessageBox.Show("Copy failed.");
-                SelectedFiles.Clear();
+                lock (bitcasa)
+                {
+                    var item = SelectItemToFileinfo();
+                    if (item.path == "") return;
+                    if (!bitcasa.copyitem((FileInfo[])SelectedFiles.ToArray(typeof(FileInfo)), item, this.progress))
+                        MessageBox.Show("Copy failed.");
+                    SelectedFiles.Clear();
+                }
             }
             if (checkBox_reload.Checked)
                 reloadview();
@@ -207,15 +347,21 @@
         {
             ArrayList delFiles = new ArrayList();
 
-            foreach (ListViewItem listitem in listView1.SelectedItems)
+            lock (typeof(FileInfo))
             {
-                if ((listitem.SubItems[0].Text == ".") || (listitem.SubItems[0].Text == "..")) continue;
-                var item = FileInfo.dirTree[listitem.SubItems[3].Text];
-                if (item.name == "") continue;
-                delFiles.Add(item);
+                foreach (ListViewItem listitem in listView1.SelectedItems)
+                {
+                    if ((listitem.SubItems[0].Text == ".") || (listitem.SubItems[0].Text == "..")) continue;
+                    var item = FileInfo.dirTree[listitem.SubItems[3].Text];
+                    if (item.name == "") continue;
+                    delFiles.Add(item);
+                }
+            }
+            lock (bitcasa)
+            {
+                if (!bitcasa.deleteitem((FileInfo[])delFiles.ToArray(typeof(FileInfo)), this.progress))
+                    MessageBox.Show("Copy failed.");
             }
-            if (!bitcasa.deleteitem((FileInfo[])delFiles.ToArray(typeof(FileInfo)), this.progress))
-                MessageBox.Show("Copy failed.");
             if (checkBox_reload.Checked)
                 reloadview();
         }
diff -ru --strip-trailing-cr BitcasaDLL-20131228/bitcasaViewer/Form1.resx BitcasaDLL-20131230/bitcasaViewer/Form1.resx
--- BitcasaDLL-20131228/bitcasaViewer/Form1.resx	2013-12-31 12:54:50.000000000 +0900
+++ BitcasaDLL-20131230/bitcasaViewer/Form1.resx	2013-12-31 11:19:00.000000000 +0900
@@ -135,4 +135,7 @@
   <metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>901, 17</value>
   </metadata>
+  <metadata name="statusStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>1025, 17</value>
+  </metadata>
 </root>
\ No newline at end of file
