diff -ruN --strip-trailing-cr BitcasaDLL-20131231/BitcasaDLL/BitcasaWrapper.cpp BitcasaDLL-20140102/BitcasaDLL/BitcasaWrapper.cpp
--- BitcasaDLL-20131231/BitcasaDLL/BitcasaWrapper.cpp	2013-12-30 00:26:12.000000000 +0900
+++ BitcasaDLL-20140102/BitcasaDLL/BitcasaWrapper.cpp	2014-01-01 08:59:04.000000000 +0900
@@ -58,6 +58,57 @@
 	return selfitem;
 }
 
+//////////////////////////////////////////////////////////////////////////////
+
+System::Collections::Generic::List<ListLocalBitcasa^>^ ListLocalBitcasa::ListDir(System::String^ rootdir)
+{
+	System::Collections::Generic::List<ListLocalBitcasa^>^ diritem = gcnew System::Collections::Generic::List<ListLocalBitcasa^>;
+
+	WIN32_FIND_DATA fd;
+	std::wstring rootstr = SystemStringToStdWString(rootdir);
+	HANDLE h = FindFirstFileExW((rootstr + L"*").c_str(),
+		FindExInfoBasic,
+		&fd,
+		FindExSearchNameMatch, NULL, 0);
+	if (h == INVALID_HANDLE_VALUE) {
+		return diritem;
+	}
+	do {
+		if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+			if ((_tcscmp(fd.cFileName, _T(".")) == 0) ||
+				(_tcscmp(fd.cFileName, _T("..")) == 0)) {
+				continue;
+			}
+			std::wstring dirname = fd.cFileName;
+			ListLocalBitcasa^ aDir = gcnew ListLocalBitcasa;
+			dirname = rootstr + dirname;
+			aDir->name = gcnew System::String(dirname.c_str());
+			INT64 t = fd.ftCreationTime.dwLowDateTime | (INT64)fd.ftCreationTime.dwHighDateTime << 32;
+			aDir->CreationTime = System::DateTime::FromFileTime(t);
+			t = fd.ftLastWriteTime.dwLowDateTime | (INT64)fd.ftLastWriteTime.dwHighDateTime << 32;
+			aDir->LastWriteTime = System::DateTime::FromFileTime(t);
+			diritem->Add(aDir);
+			diritem->AddRange(ListDir(aDir->name+"\\"));
+		}
+		else {
+			std::wstring filename = fd.cFileName;
+			ListLocalBitcasa^ aFile = gcnew ListLocalBitcasa;
+			filename = rootstr + filename;
+			aFile->name = gcnew System::String(filename.c_str());
+			INT64 t = fd.ftCreationTime.dwLowDateTime | (INT64)fd.ftCreationTime.dwHighDateTime << 32;
+			aFile->CreationTime = System::DateTime::FromFileTime(t);
+			t = fd.ftLastWriteTime.dwLowDateTime | (INT64)fd.ftLastWriteTime.dwHighDateTime << 32;
+			aFile->LastWriteTime = System::DateTime::FromFileTime(t);
+			aFile->size = fd.nFileSizeLow | (INT64)fd.nFileSizeHigh << 32;
+			diritem->Add(aFile);
+		}
+	} while (FindNextFile(h, &fd));
+	FindClose(h);
+	return diritem;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
 BitcasaWrapper::BitcasaWrapper()
 {
 	obj = new BitcasaAPI;
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/BitcasaDLL/BitcasaWrapper.h BitcasaDLL-20140102/BitcasaDLL/BitcasaWrapper.h
--- BitcasaDLL-20131231/BitcasaDLL/BitcasaWrapper.h	2013-12-30 00:26:12.000000000 +0900
+++ BitcasaDLL-20140102/BitcasaDLL/BitcasaWrapper.h	2014-01-01 08:12:30.000000000 +0900
@@ -55,6 +55,16 @@
 
 	};
 
+	public ref class ListLocalBitcasa
+	{
+	public:
+		System::String^ name;
+		Int64 size;
+		DateTime CreationTime;
+		DateTime LastWriteTime;
+
+		static System::Collections::Generic::List<ListLocalBitcasa^>^ ListDir(System::String^ rootdir);
+	};
 
 	public ref class jsonitemWrapper
 	{
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/BitcasaServer.cs BitcasaDLL-20140102/bitcasaViewer/BitcasaServer.cs
--- BitcasaDLL-20131231/bitcasaViewer/BitcasaServer.cs	2013-12-30 11:31:54.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/BitcasaServer.cs	2014-01-02 04:04:34.000000000 +0900
@@ -21,33 +21,33 @@
             return bitcasa.prepare();
         }
 
-        public FileInfo reloadDir(string fullpath, delegateProgressBar callback)
+        public BitcasaFileInfo reloadDir(string fullpath, delegateProgressBar callback)
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 fullpath = fullpath.TrimEnd('\\');
-                FileInfo.dirLoaded[fullpath] = false;
+                BitcasaFileInfo.dirLoaded[fullpath] = false;
                 return loadDir(fullpath, callback);
             }
         }
 
-        public FileInfo loadDir(string fullpath, delegateProgressBar callback)
+        public BitcasaFileInfo loadDir(string fullpath, delegateProgressBar callback)
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 fullpath = fullpath.TrimEnd('\\');
-                var dirItem = FileInfo.dirTree[fullpath];
-                if (!FileInfo.dirLoaded[fullpath])
+                var dirItem = BitcasaFileInfo.dirTree[fullpath];
+                if (!BitcasaFileInfo.dirLoaded[fullpath])
                 {
                     if (callback != null) callback(50);
                     var result = bitcasa.ListFolder(dirItem.path);
                     if (callback != null) callback(75);
-                    FileInfo.dirLoaded[fullpath] = true;
+                    BitcasaFileInfo.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), "");
+                        BitcasaFileInfo.GetItem((item as json_objectWrapper), "");
                     }
                 }
                 if (callback != null) callback(100);
@@ -57,42 +57,42 @@
 
         public void loadALL(delegateProgressBar callback)
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
-                FileInfo.clearDictionary();
+                BitcasaFileInfo.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;
+                BitcasaFileInfo.dirLoaded[""] = true;
+                BitcasaFileInfo.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;
+                    var path = BitcasaFileInfo.GetItem((item as json_objectWrapper), "").fullpath;
+                    BitcasaFileInfo.dirLoaded[path] = true;
                 }
                 loadall_flag = true;
                 if (callback != null) callback(100);
             }
         }
 
-        public FileInfo[] listChild(string parentpath)
+        public BitcasaFileInfo[] listChild(string parentpath)
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 ArrayList result = new ArrayList();
-                foreach (var item in FileInfo.dirTree.SkipWhile(x => !x.Key.StartsWith(parentpath)).TakeWhile(x => x.Key.StartsWith(parentpath)))
+                foreach (var item in BitcasaFileInfo.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 (BitcasaFileInfo[])result.ToArray(typeof(BitcasaFileInfo));
             }
         }
 
-        public bool download(FileInfo target, string localfilename, delegateProgressBar callback)
+        public bool download(BitcasaFileInfo target, string localfilename, delegateProgressBar callback)
         {
             if (target.id == "") return false;
             return bitcasa.DownloadFile(
@@ -109,7 +109,7 @@
                 );
         }
 
-        public bool upload(FileInfo targetdir, string localfilename, delegateProgressBar callback)
+        public bool upload(BitcasaFileInfo targetdir, string localfilename, delegateProgressBar callback)
         {
             if(callback != null) callback(0);
             if (targetdir.path == "") return false;
@@ -130,7 +130,7 @@
                 );
         }
 
-        public bool rename(FileInfo target, string newname, delegateProgressBar callback)
+        public bool rename(BitcasaFileInfo target, string newname, delegateProgressBar callback)
         {
             bool ret;
             if(callback != null) callback(0);
@@ -144,23 +144,23 @@
             {
                 ret = bitcasa.RenameFile(target.path, newname);
             }
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
-                FileInfo.dirTree.Remove(target.fullpath);
+                BitcasaFileInfo.dirTree.Remove(target.fullpath);
             }
             if(callback != null) callback(50);
-            reloadDir(FileInfo.pathtoparent(target.path), null);
+            reloadDir(BitcasaFileInfo.pathtoparent(target.path), null);
             if (callback != null) callback(100);
             return ret;
         }
         
-        public bool moveitem(FileInfo[] oldpaths, FileInfo newpath, delegateProgressBar callback)
+        public bool moveitem(BitcasaFileInfo[] oldpaths, BitcasaFileInfo newpath, delegateProgressBar callback)
         {
             bool ret = true;
             int progress = 25;
             if(callback != null) callback(progress);
             if (newpath.path == "") return false;
-            foreach(FileInfo oldpath in oldpaths){
+            foreach(BitcasaFileInfo oldpath in oldpaths){
                 if (oldpath.category == "folders")
                 {
                     ret = bitcasa.MoveFolder(oldpath.path, newpath.path, oldpath.name);
@@ -169,11 +169,11 @@
                 {
                     ret = bitcasa.MoveFile(oldpath.path, newpath.path, oldpath.name);
                 }
-                lock (typeof(FileInfo))
+                if (!ret) break;
+                lock (typeof(BitcasaFileInfo))
                 {
-                    FileInfo.dirTree.Remove(oldpath.fullpath);
+                    BitcasaFileInfo.dirTree.Remove(oldpath.fullpath);
                 }
-                if (!ret) break;
                 if (callback != null) callback(progress+=(50/oldpaths.Length));
             }
             reloadDir(newpath.fullpath, null);
@@ -181,13 +181,13 @@
             return ret;
         }
         
-        public bool copyitem(FileInfo[] oldpaths, FileInfo newpath, delegateProgressBar callback)
+        public bool copyitem(BitcasaFileInfo[] oldpaths, BitcasaFileInfo newpath, delegateProgressBar callback)
         {
             bool ret = true;
             int progress = 25;
             if (callback != null) callback(progress);
             if (newpath.path == "") return false;
-            foreach (FileInfo oldpath in oldpaths)
+            foreach (BitcasaFileInfo oldpath in oldpaths)
             {
                 if (oldpath.category == "folders")
                 {
@@ -197,11 +197,11 @@
                 {
                     ret = bitcasa.CopyFile(oldpath.path, newpath.path, oldpath.name);
                 }
-                lock (typeof(FileInfo))
+                if (!ret) break;
+                lock (typeof(BitcasaFileInfo))
                 {
-                    FileInfo.dirTree.Remove(oldpath.fullpath);
+                    BitcasaFileInfo.dirTree.Remove(oldpath.fullpath);
                 }
-                if (!ret) break;
                 if (callback != null) callback(progress += (50 / oldpaths.Length));
             }
             reloadDir(newpath.fullpath, null);
@@ -209,7 +209,7 @@
             return ret;
         }
 
-        public bool mkDir(FileInfo targetdir, string newname, delegateProgressBar callback)
+        public bool mkDir(BitcasaFileInfo targetdir, string newname, delegateProgressBar callback)
         {
             bool ret;
             if (callback != null) callback(0);
@@ -218,19 +218,19 @@
             if (callback != null) callback(25);
             ret = bitcasa.AddFolder(targetdir.path, newname);
             if (callback != null) callback(50);
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
-                reloadDir(FileInfo.pathtoparent(targetdir.path), null);
+                reloadDir(BitcasaFileInfo.pathtoparent(targetdir.path), null);
             }
             if (callback != null) callback(100);
             return ret;
         }
-        public bool deleteitem(FileInfo[] targets, delegateProgressBar callback)
+        public bool deleteitem(BitcasaFileInfo[] targets, delegateProgressBar callback)
         {
             bool ret = true;
             int progress = 25;
             if (callback != null) callback(progress);
-            foreach (FileInfo target in targets)
+            foreach (BitcasaFileInfo target in targets)
             {
                 if (target.category == "folders")
                 {
@@ -240,11 +240,11 @@
                 {
                     ret = bitcasa._DeleteFile(target.path);
                 }
-                lock (typeof(FileInfo))
+                if (!ret) break;
+                lock (typeof(BitcasaFileInfo))
                 {
-                    FileInfo.dirTree.Remove(target.fullpath);
+                    BitcasaFileInfo.dirTree.Remove(target.fullpath);
                 }
-                if (!ret) break;
                 if (callback != null) callback(progress += (50 / targets.Length));
             }
             if (callback != null) callback(100);
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/BitcasaTreeSelect.cs BitcasaDLL-20140102/bitcasaViewer/BitcasaTreeSelect.cs
--- BitcasaDLL-20131231/bitcasaViewer/BitcasaTreeSelect.cs	1970-01-01 09:00:00.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/BitcasaTreeSelect.cs	2014-01-01 18:17:12.000000000 +0900
@@ -0,0 +1,55 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace bitcasaViewer
+{
+    public partial class BitcasaTreeSelect : Form
+    {
+        Form1 owner;
+        public string SelectedPath
+        {
+            get {
+                var Node = treeView1.SelectedNode;
+                if (Node == null) return "";
+                return Node.FullPath.Substring(4);
+            }
+        }
+
+        public BitcasaTreeSelect(Form1 aOwner)
+        {
+            InitializeComponent();
+            owner = aOwner;
+        }
+
+        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
+        {
+            var Node = treeView1.SelectedNode;
+            if (Node == null) return;
+            var selectItem = Node.FullPath.Substring(4);
+
+            lock (typeof(BitcasaFileInfo))
+            {
+                Node.Nodes.Clear();
+                var treeitems = owner.ListChildren(selectItem);
+                foreach (BitcasaFileInfo items in treeitems)
+                {
+                    Node.Nodes.Add(items.name);
+                }
+                Node.Expand();
+            }
+        }
+
+        private void BitcasaTreeSelect_Shown(object sender, EventArgs e)
+        {
+            treeView1.Nodes.Clear();
+            treeView1.Nodes.Add("root");
+        }
+    }
+}
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/BitcasaTreeSelect.Designer.cs BitcasaDLL-20140102/bitcasaViewer/BitcasaTreeSelect.Designer.cs
--- BitcasaDLL-20131231/bitcasaViewer/BitcasaTreeSelect.Designer.cs	1970-01-01 09:00:00.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/BitcasaTreeSelect.Designer.cs	2014-01-01 17:58:00.000000000 +0900
@@ -0,0 +1,99 @@
+﻿namespace bitcasaViewer
+{
+    partial class BitcasaTreeSelect
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.treeView1 = new System.Windows.Forms.TreeView();
+            this.button1 = new System.Windows.Forms.Button();
+            this.button2 = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(12, 9);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(152, 12);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Select remote Bitcasa folder";
+            // 
+            // treeView1
+            // 
+            this.treeView1.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.treeView1.Location = new System.Drawing.Point(0, 38);
+            this.treeView1.Name = "treeView1";
+            this.treeView1.Size = new System.Drawing.Size(442, 403);
+            this.treeView1.TabIndex = 1;
+            this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
+            // 
+            // button1
+            // 
+            this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
+            this.button1.Location = new System.Drawing.Point(223, 9);
+            this.button1.Name = "button1";
+            this.button1.Size = new System.Drawing.Size(75, 23);
+            this.button1.TabIndex = 2;
+            this.button1.Text = "OK";
+            this.button1.UseVisualStyleBackColor = true;
+            // 
+            // button2
+            // 
+            this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.button2.Location = new System.Drawing.Point(330, 9);
+            this.button2.Name = "button2";
+            this.button2.Size = new System.Drawing.Size(75, 23);
+            this.button2.TabIndex = 3;
+            this.button2.Text = "Cancel";
+            this.button2.UseVisualStyleBackColor = true;
+            // 
+            // BitcasaTreeSelect
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(442, 441);
+            this.Controls.Add(this.button2);
+            this.Controls.Add(this.button1);
+            this.Controls.Add(this.treeView1);
+            this.Controls.Add(this.label1);
+            this.Name = "BitcasaTreeSelect";
+            this.Text = "BitcasaTreeSelect";
+            this.Shown += new System.EventHandler(this.BitcasaTreeSelect_Shown);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.TreeView treeView1;
+        private System.Windows.Forms.Button button1;
+        private System.Windows.Forms.Button button2;
+    }
+}
\ No newline at end of file
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/BitcasaTreeSelect.resx BitcasaDLL-20140102/bitcasaViewer/BitcasaTreeSelect.resx
--- BitcasaDLL-20131231/bitcasaViewer/BitcasaTreeSelect.resx	1970-01-01 09:00:00.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/BitcasaTreeSelect.resx	2014-01-01 17:58:00.000000000 +0900
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/bitcasaViewer.csproj BitcasaDLL-20140102/bitcasaViewer/bitcasaViewer.csproj
--- BitcasaDLL-20131231/bitcasaViewer/bitcasaViewer.csproj	2013-12-30 21:03:40.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/bitcasaViewer.csproj	2014-01-02 04:19:10.000000000 +0900
@@ -52,7 +52,7 @@
     <Prefer32Bit>true</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BitcasaDLL, Version=1.0.5112.22492, Culture=neutral, processorArchitecture=AMD64">
+    <Reference Include="BitcasaDLL, Version=1.0.5114.37552, Culture=neutral, processorArchitecture=AMD64">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\x64\Release\BitcasaDLL.dll</HintPath>
     </Reference>
@@ -73,6 +73,12 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="BitcasaServer.cs" />
+    <Compile Include="BitcasaTreeSelect.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="BitcasaTreeSelect.Designer.cs">
+      <DependentUpon>BitcasaTreeSelect.cs</DependentUpon>
+    </Compile>
     <Compile Include="FileInfo.cs" />
     <Compile Include="Form1.cs">
       <SubType>Form</SubType>
@@ -83,6 +89,12 @@
     <Compile Include="Form1_popup.cs">
       <SubType>Form</SubType>
     </Compile>
+    <Compile Include="FormDiff.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="FormDiff.Designer.cs">
+      <DependentUpon>FormDiff.cs</DependentUpon>
+    </Compile>
     <Compile Include="FormFind.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -97,9 +109,15 @@
     </Compile>
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="BitcasaTreeSelect.resx">
+      <DependentUpon>BitcasaTreeSelect.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="Form1.resx">
       <DependentUpon>Form1.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="FormDiff.resx">
+      <DependentUpon>FormDiff.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="FormFind.resx">
       <DependentUpon>FormFind.cs</DependentUpon>
     </EmbeddedResource>
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/FileInfo.cs BitcasaDLL-20140102/bitcasaViewer/FileInfo.cs
--- BitcasaDLL-20131231/bitcasaViewer/FileInfo.cs	2013-12-28 19:52:08.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/FileInfo.cs	2014-01-02 21:09:58.000000000 +0900
@@ -3,21 +3,57 @@
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.IO;
 using BitcasaDLL;
 
 namespace bitcasaViewer
 {
+    class LocalFileInfo
+    {
+        public string name;
+        public Int64 size;
+        public DateTime CreationTime;
+        public DateTime LastWriteTime;
 
-    class FileInfo
+        public static List<LocalFileInfo> ListDir(string rootdir)
+        {
+            List<LocalFileInfo> diritem = new List<LocalFileInfo>();
+            foreach (string entry in Directory.GetDirectories(rootdir))
+            {
+                LocalFileInfo aDir = new LocalFileInfo();
+                var info = new DirectoryInfo(entry);
+                aDir.name = info.FullName;
+                aDir.CreationTime = info.CreationTime;
+                aDir.LastWriteTime = info.LastWriteTime;
+                diritem.Add(aDir);
+                diritem.AddRange(ListDir(aDir.name));
+            }
+            foreach (string entry in Directory.GetFiles(rootdir))
+            {
+                LocalFileInfo aDir = new LocalFileInfo();
+                var info = new FileInfo(entry);
+                aDir.name = info.FullName;
+                aDir.CreationTime = info.CreationTime;
+                aDir.LastWriteTime = info.LastWriteTime;
+                diritem.Add(aDir);
+            }
+            return diritem;
+        }
+    }
+
+    public class BitcasaFileInfo
     {
-        public static SortedDictionary<string, FileInfo> dirTree;
+        public static SortedDictionary<string, BitcasaFileInfo> dirTree;
         public static SortedDictionary<string, string> PathDirMap;
         public static SortedDictionary<string, bool> dirLoaded;
+        public static SortedDictionary<string, BitcasaFileInfo> BitcasaDrive;
         public static void clearDictionary()
         {
             dirTree.Clear();
             PathDirMap.Clear();
-            FileInfo newItem = new FileInfo();
+            dirLoaded.Clear();
+            BitcasaDrive.Clear();
+            BitcasaFileInfo newItem = new BitcasaFileInfo();
             newItem.name = "\\";
             newItem.path = "/";
             dirTree[newItem.fullpath] = newItem;
@@ -29,6 +65,7 @@
         }
 
         public string parentpath;
+        public ListLocalBitcasa localinfo;
         //common
         public string category;
         public string name;
@@ -52,65 +89,113 @@
             get { return parentpath + name; }
         }
 
-        static FileInfo()
+        static BitcasaFileInfo()
         {
-            dirTree = new SortedDictionary<string, FileInfo>();
+            dirTree = new SortedDictionary<string, BitcasaFileInfo>();
             PathDirMap = new SortedDictionary<string, string>();
             dirLoaded = new SortedDictionary<string, bool>();
+            BitcasaDrive = new SortedDictionary<string, BitcasaFileInfo>();
             clearDictionary();
         }
 
         public static string pathtoparent(string path)
         {
-            string parent = path.Substring(0, path.LastIndexOf('/'));
-            return PathDirMap[parent]+"\\";
-        }
-
-        public static FileInfo GetItem(json_objectWrapper Item, string parent)
-        {
-            FileInfo newItem = new FileInfo();
-
-            newItem.parentpath = (parent == "") ? pathtoparent(Item["path"].GetString()) : parent;
-
-            jsonitemWrapper entry;
-            entry = Item["category"];
-            newItem.category = entry.GetString();
-            entry = Item["name"];
-            newItem.name = entry.GetString();
-            entry = Item["mtime"];
-            newItem.mtime = entry.GetDouble();
-            entry = Item["path"];
-            newItem.path = entry.GetString();
-            entry = Item["type"];
-            newItem.type = (int)entry.GetDouble();
-            //folder
-            entry = Item["mount_point"];
-            newItem.mount_point = entry.GetString();
-            entry = Item["mirrored"];
-            newItem.mirrored = entry.GetBool();
-            entry = Item["origin_device"];
-            newItem.origin_device = entry.GetString();
-            entry = Item["origin_device_id"];
-            newItem.origin_device_id = entry.GetString();
-            entry = Item["sync_type"];
-            newItem.sync_type = entry.GetString();
-            //file
-            entry = Item["manifest_name"];
-            newItem.manifest_name = entry.GetString();
-            entry = Item["id"];
-            newItem.id = entry.GetString();
-            entry = Item["incomplete"];
-            newItem.incomplete = entry.GetBool();
-            entry = Item["size"];
-            newItem.size = entry.GetInteger();
-
-            dirTree[newItem.fullpath] = newItem;
-            PathDirMap[newItem.path] = newItem.fullpath;
-            dirLoaded[newItem.fullpath] = false;
-
+            lock (typeof(BitcasaFileInfo))
+            {
+                string parent = path.Substring(0, path.LastIndexOf('/'));
+                return PathDirMap[parent] + "\\";
+            }
+        }
+        public static string fullpathToBitcasaPath(string fullpath)
+        {
+            lock (typeof(BitcasaFileInfo))
+            {
+                var pos = fullpath.IndexOf("\\", 1);
+                string parent = fullpath.Substring(0, (pos < 0)? 0: pos);
+                string child = fullpath.Substring(parent.Length);
+                if (parent == "")
+                {
+                    parent = child;
+                    child = "";
+                }
+                BitcasaFileInfo rootitem;
+                if (!dirTree.TryGetValue(parent, out rootitem)) return "";
+                const string infstr = "Bitcasa Infinite Drive";
+                if (rootitem.name == infstr)
+                {
+                    return (child == "") ? ("\\" + infstr) : ("\\" + infstr + child);
+                }
+                const string submount = "%%%HOME%%%/Bitcasa";
+                if (rootitem.mount_point.IndexOf(submount) == 0)
+                {
+                    return "\\" + infstr + rootitem.mount_point.Substring(submount.Length).Replace('/', '\\') + child;
+                }
+                if (rootitem.mount_point != "")
+                {
+                    return "\\" + rootitem.name + child;
+                }
+                return "";
+            }
+        }
+
+        public static BitcasaFileInfo GetItem(json_objectWrapper Item, string parent)
+        {
+            BitcasaFileInfo newItem = new BitcasaFileInfo();
+
+            try
+            {
+                newItem.parentpath = (parent == "") ? pathtoparent(Item["path"].GetString()) : parent;
+
+                jsonitemWrapper entry;
+                entry = Item["category"];
+                newItem.category = entry.GetString();
+                entry = Item["name"];
+                newItem.name = entry.GetString();
+                entry = Item["mtime"];
+                newItem.mtime = entry.GetDouble();
+                entry = Item["path"];
+                newItem.path = entry.GetString();
+                entry = Item["type"];
+                newItem.type = (int)entry.GetDouble();
+                //folder
+                entry = Item["mount_point"];
+                newItem.mount_point = entry.GetString();
+                entry = Item["mirrored"];
+                newItem.mirrored = entry.GetBool();
+                entry = Item["origin_device"];
+                newItem.origin_device = entry.GetString();
+                entry = Item["origin_device_id"];
+                newItem.origin_device_id = entry.GetString();
+                entry = Item["sync_type"];
+                newItem.sync_type = entry.GetString();
+                //file
+                entry = Item["manifest_name"];
+                newItem.manifest_name = entry.GetString();
+                entry = Item["id"];
+                newItem.id = entry.GetString();
+                entry = Item["incomplete"];
+                newItem.incomplete = entry.GetBool();
+                entry = Item["size"];
+                newItem.size = entry.GetInteger();
+
+                lock (typeof(BitcasaFileInfo))
+                {
+                    dirTree[newItem.fullpath] = newItem;
+                    PathDirMap[newItem.path] = newItem.fullpath;
+                    dirLoaded[newItem.fullpath] = false;
+
+                    BitcasaFileInfo olditem;
+                    if (BitcasaDrive.TryGetValue(BitcasaFileInfo.fullpathToBitcasaPath(newItem.fullpath), out olditem))
+                    {
+                        newItem.localinfo = olditem.localinfo;
+                    }
+                    BitcasaDrive[BitcasaFileInfo.fullpathToBitcasaPath(newItem.fullpath)] = newItem;
+                }
+            }
+            catch { return new BitcasaFileInfo(); }
             return newItem;
         }
-        public static FileInfo GetItem(json_objectWrapper Item)
+        public static BitcasaFileInfo GetItem(json_objectWrapper Item)
         {
             return GetItem(Item, "\\");
         }
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/Form1.cs BitcasaDLL-20140102/bitcasaViewer/Form1.cs
--- BitcasaDLL-20131231/bitcasaViewer/Form1.cs	2013-12-30 17:13:18.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/Form1.cs	2014-01-02 12:48:24.000000000 +0900
@@ -32,7 +32,7 @@
         }
 
 
-        private void listFileItems(FileInfo[] items, bool dotfiles)
+        private void listFileItems(BitcasaFileInfo[] items, bool dotfiles)
         {
             listView1.BeginUpdate();
             listView1.Items.Clear();
@@ -43,11 +43,11 @@
                 string[] upitem = { "..", "", "", "", "", "" };
                 listView1.Items.Add(new ListViewItem(upitem));
             }
-            foreach (FileInfo item in items)
+            foreach (BitcasaFileInfo item in items)
             {
                 string[] itemstr ={
                                        item.name,
-                                       FileInfo.mtimeToString(item.mtime),
+                                       BitcasaFileInfo.mtimeToString(item.mtime),
                                        (item.category == "folders")? "<dir>": item.size.ToString(),
                                        item.fullpath,
                                        item.path,
@@ -59,14 +59,15 @@
             listView1.EndUpdate();
         }
 
-        private void detailShowFileItems(FileInfo item)
+        private void detailShowFileItems(BitcasaFileInfo item)
         {
+            if (item == null) return;
             listBox1.Items.Clear();
             listBox1.Items.Add("category : " + item.category);
             listBox1.Items.Add("name : " + item.name);
             listBox1.Items.Add("path : " + item.path);
             listBox1.Items.Add("mtime : " + item.mtime.ToString());
-            listBox1.Items.Add("        " + FileInfo.mtimeToString(item.mtime));
+            listBox1.Items.Add("        " + BitcasaFileInfo.mtimeToString(item.mtime));
             listBox1.Items.Add("type  : " + item.type.ToString());
             if (item.category == "folders")
             {
@@ -83,30 +84,46 @@
                 listBox1.Items.Add("incomplete : " + item.incomplete.ToString());
                 listBox1.Items.Add("size : " + item.size.ToString());
             }
+            if (item.localinfo != null)
+            {
+                listBox1.Items.Add("local name : " + item.localinfo.name);
+                listBox1.Items.Add("local size : " + item.localinfo.size);
+                listBox1.Items.Add("local ctime : " + item.localinfo.CreationTime.ToString());
+                listBox1.Items.Add("local mtime : " + item.localinfo.LastWriteTime.ToString());
+            }
         }
 
-        private FileInfo SelectItemToFileinfo()
+        private BitcasaFileInfo SelectItemToFileinfo()
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 var seletedItem = listView1.SelectedItems[0];
-                var item = FileInfo.dirTree[seletedItem.SubItems[3].Text];
+                var item = BitcasaFileInfo.dirTree[seletedItem.SubItems[3].Text];
                 if (seletedItem.SubItems[0].Text == ".")
                 {
-                    item = FileInfo.dirTree[treeView1.SelectedNode.FullPath.Substring(4)];
+                    item = BitcasaFileInfo.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)];
+                        item = BitcasaFileInfo.dirTree[moveto.FullPath.Substring(4)];
                     else
-                        item = FileInfo.dirTree["\\"];
+                        item = BitcasaFileInfo.dirTree["\\"];
                 }
                 return item;
             }
         }
 
+        public BitcasaFileInfo[] ListChildren(string parent)
+        {
+            lock (typeof(BitcasaFileInfo))
+            {
+                var treeparent = bitcasa.loadDir(parent, this.progress);
+                return bitcasa.listChild(treeparent.fullpath);
+            }
+        }
+
         private void reloadview()
         {
             try
@@ -124,16 +141,22 @@
 
                     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)
+                    lock (typeof(BitcasaFileInfo))
                     {
-                        Node.Nodes.Add(items.name);
-                    }
-                    Node.Expand();
+                        try
+                        {
+                            Node.Nodes.Clear();
+                            var treeitems = ListChildren(selectItem);
+                            foreach (BitcasaFileInfo items in treeitems)
+                            {
+                                Node.Nodes.Add(items.name);
+                            }
+                            Node.Expand();
 
-                    listFileItems(treeitems, true);
+                            listFileItems(treeitems, true);
+                        }
+                        catch { return; }
+                    }
                 }
             }
             finally
@@ -177,7 +200,7 @@
 
         private void listView1_SelectedIndexChanged(object sender, EventArgs e)
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 if (listView1.SelectedItems.Count > 1)
                 {
@@ -188,9 +211,13 @@
                     if (listView1.SelectedItems.Count > 1000) return;
                     foreach (ListViewItem selectitem in listView1.SelectedItems)
                     {
-                        var item = FileInfo.dirTree[selectitem.SubItems[3].Text];
-                        sizesum += item.size;
-                        if (item.category == "folders") dircount++;
+                        try
+                        {
+                            var item = BitcasaFileInfo.dirTree[selectitem.SubItems[3].Text];
+                            sizesum += item.size;
+                            if (item.category == "folders") dircount++;
+                        }
+                        catch { continue; }
                     }
                     listBox1.Items.Add(sizesum.ToString() + " bytes");
                     listBox1.Items.Add(dircount.ToString() + " dirs");
@@ -203,23 +230,27 @@
                         listBox1.Items.Clear();
                         return;
                     }
-                    var item = FileInfo.dirTree[listView1.SelectedItems[0].SubItems[3].Text];
-
-                    if (listView1.SelectedItems[0].SubItems[0].Text == ".")
-                    {
-                        var self = treeView1.SelectedNode.FullPath.Substring(4);
-                        if (self == "") return;
-                        item = FileInfo.dirTree[self];
-                    }
-                    if (listView1.SelectedItems[0].SubItems[0].Text == "..")
+                    try
                     {
-                        var upitem = treeView1.SelectedNode.Parent;
-                        if (upitem == null) return;
-                        var self = upitem.FullPath.Substring(4);
-                        if (self == "") return;
-                        item = FileInfo.dirTree[self];
+                        var item = BitcasaFileInfo.dirTree[listView1.SelectedItems[0].SubItems[3].Text];
+
+                        if (listView1.SelectedItems[0].SubItems[0].Text == ".")
+                        {
+                            var self = treeView1.SelectedNode.FullPath.Substring(4);
+                            if (self == "") return;
+                            item = BitcasaFileInfo.dirTree[self];
+                        }
+                        if (listView1.SelectedItems[0].SubItems[0].Text == "..")
+                        {
+                            var upitem = treeView1.SelectedNode.Parent;
+                            if (upitem == null) return;
+                            var self = upitem.FullPath.Substring(4);
+                            if (self == "") return;
+                            item = BitcasaFileInfo.dirTree[self];
+                        }
+                        detailShowFileItems(item);
                     }
-                    detailShowFileItems(item);
+                    catch { return; }
                 }
             }
         }
@@ -254,28 +285,32 @@
         {
             if (listView1.SelectedItems.Count == 1)
             {
-                lock (typeof(FileInfo))
+                lock (typeof(BitcasaFileInfo))
                 {
                     if (ongoing)
                     {
                         MessageBox.Show("now processing...");
                         return;
                     }
-                    var item = listView1.SelectedItems[0].SubItems[0].Text;
-                    if (item == ".") return;
-                    if (item == "..")
+                    try
                     {
-                        var moveto = treeView1.SelectedNode.Parent;
-                        if (moveto != null) treeView1.SelectedNode = moveto;
+                        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 = BitcasaFileInfo.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];
-                    listView1.Items.Clear();
-                    listView1.BeginUpdate();
-                    decendTree(diritem.fullpath);
-                    listView1.EndUpdate();
-                    treeView1.Focus();
+                    catch { return; }
                 }
             }
         }
@@ -355,6 +390,7 @@
             listView1.Enabled = true;
             treeView1.Enabled = true;
             scanAllToolStripMenuItem.Text = "Find...";
+            overlyToolStripMenuItem.Enabled = true;
             Update();
             loadall_flag = true;
             reloadview();
@@ -366,14 +402,14 @@
         {
             if (findform.datemin != FormFind.InvalidDate)
             {
-                if (FileInfo.DateTimeTomtime(findform.datemin) > FileInfo.dirTree[key].mtime)
+                if (BitcasaFileInfo.DateTimeTomtime(findform.datemin) > BitcasaFileInfo.dirTree[key].mtime)
                 {
                     return false;
                 }
             }
             if (findform.datemax != FormFind.InvalidDate)
             {
-                if (FileInfo.DateTimeTomtime(findform.datemax) < FileInfo.dirTree[key].mtime)
+                if (BitcasaFileInfo.DateTimeTomtime(findform.datemax) < BitcasaFileInfo.dirTree[key].mtime)
                 {
                     return false;
                 }
@@ -382,18 +418,18 @@
         }
         private bool Sizetest(string key)
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 if (findform.sizemin >= 0)
                 {
-                    if (findform.sizemin > FileInfo.dirTree[key].size)
+                    if (findform.sizemin > BitcasaFileInfo.dirTree[key].size)
                     {
                         return false;
                     }
                 }
                 if (findform.sizemax >= 0)
                 {
-                    if (findform.sizemax < FileInfo.dirTree[key].size)
+                    if (findform.sizemax < BitcasaFileInfo.dirTree[key].size)
                     {
                         return false;
                     }
@@ -406,7 +442,7 @@
         {
             if (findform.ShowDialog() == DialogResult.OK)
             {
-                lock (typeof(FileInfo))
+                lock (typeof(BitcasaFileInfo))
                 {
                     toolStripStatusLabel1.Text = "find...";
                     Update();
@@ -418,7 +454,7 @@
                     if (findform.IsRegular)
                     {
                         Regex regtest = new Regex(findform.findstr);
-                        foreach (string key in FileInfo.dirTree.Keys)
+                        foreach (string key in BitcasaFileInfo.dirTree.Keys)
                         {
                             if (!regtest.IsMatch(key))
                                 continue;
@@ -426,12 +462,12 @@
                                 continue;
                             if (!Timetest(key))
                                 continue;
-                            hit.Add(FileInfo.dirTree[key]);
+                            hit.Add(BitcasaFileInfo.dirTree[key]);
                         }
                     }
                     else
                     {
-                        foreach (string key in FileInfo.dirTree.Keys)
+                        foreach (string key in BitcasaFileInfo.dirTree.Keys)
                         {
                             if (key.IndexOf(findform.findstr) < 0)
                                 continue;
@@ -439,11 +475,11 @@
                                 continue;
                             if (!Timetest(key))
                                 continue;
-                            hit.Add(FileInfo.dirTree[key]);
+                            hit.Add(BitcasaFileInfo.dirTree[key]);
                         }
                     }
                     progress(50);
-                    listFileItems((FileInfo[])hit.ToArray(typeof(FileInfo)), false);
+                    listFileItems((BitcasaFileInfo[])hit.ToArray(typeof(BitcasaFileInfo)), false);
                     progress(100);
                     toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
                     toolStripStatusLabel1.Text = "";
@@ -451,5 +487,67 @@
             }
         }
 
+        private void biToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (ongoing)
+            {
+                MessageBox.Show("now processing...");
+                return;
+            }
+            const string infstr = "Bitcasa Infinite Drive";
+            lock (typeof(BitcasaFileInfo))
+            {
+                using (var diff = new FormDiff())
+                {
+                    progress(50);
+                    toolStripStatusLabel1.Text = "loading...";
+                    Update();
+                    diff.diff("I:\\", "\\" + infstr, true);
+                    diff.ShowDialog();
+                }
+
+                progress(100);
+                toolStripStatusLabel1.Text = "";
+            }
+        }
+
+        private void otherToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (ongoing)
+            {
+                MessageBox.Show("now processing...");
+                return;
+            }
+            lock (typeof(BitcasaFileInfo))
+            {
+                string left;
+                string right;
+                using (var selecttree = new BitcasaTreeSelect(this))
+                {
+                    if (selecttree.ShowDialog() != DialogResult.OK) return;
+                    right = selecttree.SelectedPath;
+                }
+                if (right == "") right = "\\";
+                using (var localtree = new FolderBrowserDialog())
+                {
+                    localtree.Description = "Select local root folder";
+                    if (localtree.ShowDialog() != DialogResult.OK) return;
+                    left = localtree.SelectedPath;
+                }
+
+                using (var diff = new FormDiff())
+                {
+                    progress(50);
+                    toolStripStatusLabel1.Text = "loading...";
+                    Update();
+                    diff.diff(left + "\\", right, false);
+                    diff.ShowDialog();
+                }
+
+                progress(100);
+                toolStripStatusLabel1.Text = "";
+            }
+        }
+
     }
 }
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/Form1.Designer.cs BitcasaDLL-20140102/bitcasaViewer/Form1.Designer.cs
--- BitcasaDLL-20131231/bitcasaViewer/Form1.Designer.cs	2013-12-30 01:18:00.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/Form1.Designer.cs	2014-01-01 20:03:34.000000000 +0900
@@ -33,6 +33,9 @@
             this.loginToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.reloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.scanAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.overlyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.biToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.otherToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
             this.downloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.uploadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -84,7 +87,8 @@
             this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.loginToolStripMenuItem,
             this.reloadToolStripMenuItem,
-            this.scanAllToolStripMenuItem});
+            this.scanAllToolStripMenuItem,
+            this.overlyToolStripMenuItem});
             this.menuStrip1.Location = new System.Drawing.Point(0, 0);
             this.menuStrip1.Name = "menuStrip1";
             this.menuStrip1.Size = new System.Drawing.Size(807, 26);
@@ -114,6 +118,30 @@
             this.scanAllToolStripMenuItem.Text = "ScanAll";
             this.scanAllToolStripMenuItem.Click += new System.EventHandler(this.scanAllToolStripMenuItem_Click);
             // 
+            // overlyToolStripMenuItem
+            // 
+            this.overlyToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.biToolStripMenuItem,
+            this.otherToolStripMenuItem});
+            this.overlyToolStripMenuItem.Enabled = false;
+            this.overlyToolStripMenuItem.Name = "overlyToolStripMenuItem";
+            this.overlyToolStripMenuItem.Size = new System.Drawing.Size(58, 22);
+            this.overlyToolStripMenuItem.Text = "Overly";
+            // 
+            // biToolStripMenuItem
+            // 
+            this.biToolStripMenuItem.Name = "biToolStripMenuItem";
+            this.biToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.biToolStripMenuItem.Text = "Bitcasa";
+            this.biToolStripMenuItem.Click += new System.EventHandler(this.biToolStripMenuItem_Click);
+            // 
+            // otherToolStripMenuItem
+            // 
+            this.otherToolStripMenuItem.Name = "otherToolStripMenuItem";
+            this.otherToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.otherToolStripMenuItem.Text = "Other ...";
+            this.otherToolStripMenuItem.Click += new System.EventHandler(this.otherToolStripMenuItem_Click);
+            // 
             // contextMenuStrip1
             // 
             this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -197,7 +225,7 @@
             // 
             // folderBrowserDialog1
             // 
-            this.folderBrowserDialog1.Description = "ダウンロード先フォルダの選択";
+            this.folderBrowserDialog1.Description = "Select download folder";
             this.folderBrowserDialog1.RootFolder = System.Environment.SpecialFolder.MyComputer;
             // 
             // openFileDialog1
@@ -339,7 +367,7 @@
             // toolStripStatusLabel1
             // 
             this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
-            this.toolStripStatusLabel1.Size = new System.Drawing.Size(580, 17);
+            this.toolStripStatusLabel1.Size = new System.Drawing.Size(611, 17);
             this.toolStripStatusLabel1.Spring = true;
             this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
             // 
@@ -435,6 +463,9 @@
         private System.Windows.Forms.CheckBox checkBox_reload;
         private System.Windows.Forms.StatusStrip statusStrip2;
         private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
+        private System.Windows.Forms.ToolStripMenuItem overlyToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem biToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem otherToolStripMenuItem;
     }
 }
 
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/Form1_popup.cs BitcasaDLL-20140102/bitcasaViewer/Form1_popup.cs
--- BitcasaDLL-20131231/bitcasaViewer/Form1_popup.cs	2013-12-30 11:31:54.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/Form1_popup.cs	2014-01-02 12:48:24.000000000 +0900
@@ -38,14 +38,18 @@
                     folder_flag = true;
                     continue;
                 }
-                var item = FileInfo.dirTree[listitem.SubItems[3].Text];
-                if (item.id != "")
+                try
                 {
-                    file_flag = true;
-                    continue;
+                    var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
+                    if (item.id != "")
+                    {
+                        file_flag = true;
+                        continue;
+                    }
+                    if (item.category == "folders")
+                        folder_flag = true;
                 }
-                if (item.category == "folders")
-                    folder_flag = true;
+                catch { return; }
             }
             if (file_flag && folder_flag)
             {
@@ -75,43 +79,56 @@
         {
             if (listView1.SelectedItems.Count == 1)
             {
-                FileInfo item;
-                lock(typeof(FileInfo))
-                    item = FileInfo.dirTree[listView1.SelectedItems[0].SubItems[3].Text];
-                if (item.id == "") return;
-                saveFileDialog1.FileName = item.name;
+                var fullpath = listView1.SelectedItems[0].SubItems[3].Text;
+                string itemname;
+                lock (typeof(BitcasaFileInfo))
+                {
+                    var item = BitcasaFileInfo.dirTree[fullpath];
+                    if (item.id == "") return;
+                    itemname = item.name;
+                }
+                saveFileDialog1.FileName = itemname;
                 if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                 {
                     progress(0);
                     ongoing = true;
-                    toolStripStatusLabel1.Text = "downloading... " + item.name;
-                    var ret = await Task.Run(
-                        () =>
-                        {
-                            lock (bitcasa)
+                    toolStripStatusLabel1.Text = "downloading... " + itemname;
+                    try
+                    {
+                        var ret = await Task.Run(
+                            () =>
                             {
-                                return bitcasa.download(
-                                    item,
-                                    saveFileDialog1.FileName,
-                                    (int p) => this.BeginInvoke(
-                                        (BitcasaServer.delegateProgressBar)(
-                                            (int x) =>
-                                            {
-                                                progress(x);
-                                            }),
-                                        new object[] { p }
-                                    )
-                                );
-                            }
-                        });
+                                lock (bitcasa)
+                                    lock (typeof(BitcasaFileInfo))
+                                    {
+                                        var item = BitcasaFileInfo.dirTree[fullpath];
+                                        return bitcasa.download(
+                                            item,
+                                            saveFileDialog1.FileName,
+                                            (int p) => this.BeginInvoke(
+                                                (BitcasaServer.delegateProgressBar)(
+                                                    (int x) =>
+                                                    {
+                                                        progress(x);
+                                                    }),
+                                                new object[] { p }
+                                            )
+                                        );
+                                    }
+                            });
 
-                    if (ret)
-                    {
-                        progress(100);
+                        if (ret)
+                        {
+                            progress(100);
+                        }
+                        else
+                        {
+                            MessageBox.Show("download failed.");
+                            progress(0);
+                        }
                     }
-                    else
+                    catch
                     {
-                        MessageBox.Show("download failed.");
                         progress(0);
                     }
                     toolStripStatusLabel1.Text = "";
@@ -122,53 +139,64 @@
             {
                 if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                 {
-                    ArrayList targetitems = new ArrayList();
-                    lock (typeof(FileInfo))
+                    ArrayList targetfulpass = new ArrayList();
+                    lock (typeof(BitcasaFileInfo))
                     {
                         foreach (ListViewItem listitem in listView1.SelectedItems)
                         {
-                            var item = FileInfo.dirTree[listitem.SubItems[3].Text];
+                            var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
                             if (item.id == "") continue;
 
-                            targetitems.Add(item);
+                            targetfulpass.Add(listitem.SubItems[3].Text);
                         }
                     }
                     progress(0);
                     ongoing = true;
-                    var result = await Task.Run(
-                        () =>
-                        {
-                            lock (bitcasa)
+                    try
+                    {
+                        var result = await Task.Run(
+                            () =>
                             {
-                                var path = folderBrowserDialog1.SelectedPath + "\\";
-                                bool ret = true;
-                                foreach (FileInfo item in targetitems)
+                                lock (bitcasa)
                                 {
-                                    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;
+                                    var path = folderBrowserDialog1.SelectedPath + "\\";
+                                    bool ret = true;
+                                    foreach (string target in targetfulpass)
+                                    {
+                                        lock (typeof(BitcasaFileInfo))
+                                        {
+                                            var item = BitcasaFileInfo.dirTree[target];
+                                            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;
                                 }
-                                return ret;
-                            }
-                        });
-                    if (result)
-                    {
-                        progress(100);
+                            });
+                        if (result)
+                        {
+                            progress(100);
+                        }
+                        else
+                        {
+                            MessageBox.Show("download failed.");
+                            progress(0);
+                        }
                     }
-                    else
+                    catch
                     {
-                        MessageBox.Show("download failed.");
                         progress(0);
                     }
                     toolStripStatusLabel1.Text = "";
@@ -179,8 +207,7 @@
 
         private async void uploadToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            var item = SelectItemToFileinfo();
-            if (item.path == "") return;
+            if (SelectItemToFileinfo().path == "") return;
             if (openFileDialog1.ShowDialog() == DialogResult.OK)
             {
                 progress(0);
@@ -189,42 +216,52 @@
                 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)
+                try
                 {
-                    progress(100);
+                    var ret = await Task.Run(
+                        () =>
+                        {
+                            lock (bitcasa)
+                            {
+                                lock (typeof(BitcasaFileInfo))
+                                {
+                                    var item = SelectItemToFileinfo();
+                                    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);
+                    }
                 }
-                else
+                catch
                 {
-                    MessageBox.Show("upload not completed(failed or too slow response).");
                     progress(0);
                 }
                 toolStripStatusLabel1.Text = "";
@@ -238,51 +275,58 @@
 
         private void mkDirToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            var item = SelectItemToFileinfo();
-            if (item.path == "") return;
-            var dialog = new FormInput();
-            dialog.LabelText = "enter new name";
-            dialog.InputString = "";
-            if (dialog.ShowDialog() == DialogResult.OK)
+            lock (typeof(BitcasaFileInfo))
             {
-                if (dialog.InputString == item.name) return;
-                if (dialog.InputString == "") return;
-
-                lock (bitcasa)
+                var item = SelectItemToFileinfo();
+                if (item.path == "") return;
+                var dialog = new FormInput();
+                dialog.LabelText = "enter new name";
+                dialog.InputString = "";
+                if (dialog.ShowDialog() == DialogResult.OK)
                 {
-                    if (!bitcasa.mkDir(item, dialog.InputString, this.progress))
+                    if (dialog.InputString == item.name) return;
+                    if (dialog.InputString == "") return;
+
+                    lock (bitcasa)
                     {
-                        MessageBox.Show("AddFolder failed.");
-                        return;
+                        if (!bitcasa.mkDir(item, dialog.InputString, this.progress))
+                        {
+                            MessageBox.Show("AddFolder failed.");
+                            return;
+                        }
                     }
                 }
+                if (checkBox_reload.Checked)
+                    reloadview();
             }
-            if (checkBox_reload.Checked)
-                reloadview();
         }
 
         private void renameToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
-                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)
+                try
                 {
-                    if (dialog.InputString == item.name) return;
-                    lock (bitcasa)
+                    var seletedItem = listView1.SelectedItems[0];
+                    if ((seletedItem.SubItems[0].Text == ".") || (seletedItem.SubItems[0].Text == "..")) return;
+                    var item = BitcasaFileInfo.dirTree[seletedItem.SubItems[3].Text];
+                    var dialog = new FormInput();
+                    dialog.LabelText = "enter new name";
+                    dialog.InputString = item.name;
+                    if (dialog.ShowDialog() == DialogResult.OK)
                     {
-                        if (!bitcasa.rename(item, dialog.InputString, this.progress))
+                        if (dialog.InputString == item.name) return;
+                        lock (bitcasa)
                         {
-                            MessageBox.Show("Rename failed.");
-                            return;
+                            if (!bitcasa.rename(item, dialog.InputString, this.progress))
+                            {
+                                MessageBox.Show("Rename failed.");
+                                return;
+                            }
                         }
                     }
                 }
+                catch { return; }
                 if (checkBox_reload.Checked)
                     reloadview();
             }
@@ -290,13 +334,17 @@
 
         private void pushSelectedList()
         {
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 foreach (ListViewItem listitem in listView1.SelectedItems)
                 {
-                    var item = FileInfo.dirTree[listitem.SubItems[3].Text];
-                    if (item.name == "") continue;
-                    SelectedFiles.Add(item);
+                    try
+                    {
+                        var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
+                        if (item.name == "") continue;
+                        SelectedFiles.Add(item);
+                    }
+                    catch { continue; }
                 }
             }
         }
@@ -311,11 +359,14 @@
             {
                 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();
+                    lock (typeof(BitcasaFileInfo))
+                    {
+                        var item = SelectItemToFileinfo();
+                        if (item.path == "") return;
+                        if (!bitcasa.moveitem((BitcasaFileInfo[])SelectedFiles.ToArray(typeof(BitcasaFileInfo)), item, this.progress))
+                            MessageBox.Show("Move failed.");
+                        SelectedFiles.Clear();
+                    }
                 }
             }
             if (checkBox_reload.Checked)
@@ -332,11 +383,14 @@
             {
                 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();
+                    lock (typeof(BitcasaFileInfo))
+                    {
+                        var item = SelectItemToFileinfo();
+                        if (item.path == "") return;
+                        if (!bitcasa.copyitem((BitcasaFileInfo[])SelectedFiles.ToArray(typeof(BitcasaFileInfo)), item, this.progress))
+                            MessageBox.Show("Copy failed.");
+                        SelectedFiles.Clear();
+                    }
                 }
             }
             if (checkBox_reload.Checked)
@@ -347,20 +401,24 @@
         {
             ArrayList delFiles = new ArrayList();
 
-            lock (typeof(FileInfo))
+            lock (typeof(BitcasaFileInfo))
             {
                 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);
+                    try
+                    {
+                        var item = BitcasaFileInfo.dirTree[listitem.SubItems[3].Text];
+                        if (item.name == "") continue;
+                        delFiles.Add(item);
+                    }
+                    catch { continue; }
                 }
             }
             lock (bitcasa)
             {
-                if (!bitcasa.deleteitem((FileInfo[])delFiles.ToArray(typeof(FileInfo)), this.progress))
-                    MessageBox.Show("Copy failed.");
+                if (!bitcasa.deleteitem((BitcasaFileInfo[])delFiles.ToArray(typeof(BitcasaFileInfo)), this.progress))
+                    MessageBox.Show("Delete failed.");
             }
             if (checkBox_reload.Checked)
                 reloadview();
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/FormDiff.cs BitcasaDLL-20140102/bitcasaViewer/FormDiff.cs
--- BitcasaDLL-20131231/bitcasaViewer/FormDiff.cs	1970-01-01 09:00:00.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/FormDiff.cs	2014-01-02 03:47:22.000000000 +0900
@@ -0,0 +1,159 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using BitcasaDLL;
+
+namespace bitcasaViewer
+{
+    public partial class FormDiff : Form
+    {
+        List<string> diffItemList;
+        string leftpath;
+        string rightpath;
+
+        class item
+        {
+            public bool left;
+            public bool right;
+            public string key;
+
+            public item(string K, bool L, bool R)
+            {
+                key = K;
+                left = L;
+                right = R;
+            }
+        }
+
+        public FormDiff()
+        {
+            InitializeComponent();
+            diffItemList = new List<string>();
+        }
+
+        public void diff(string localrootdir, string prefix, bool save)
+        {
+            SortedDictionary<string, item> difflist = new SortedDictionary<string, item>();
+            
+            leftpath = localrootdir;
+            rightpath = prefix;
+            label1.Text = "left : " + leftpath;
+            label2.Text = "right: " + rightpath;
+
+            //right(remote)
+            foreach(string akey in BitcasaFileInfo.BitcasaDrive.Keys)
+            {
+                string key = akey;
+                if (key.IndexOf(prefix) == 0)
+                {
+                    key = key.Substring(prefix.Length).TrimStart('\\');
+                }
+                else
+                {
+                    continue;
+                }
+                if (key == "") continue;
+                if (BitcasaFileInfo.BitcasaDrive[akey].name == null) continue;
+                difflist[key] = new item(akey, false, true);
+            }
+            //left(local)
+            foreach (ListLocalBitcasa akey in ListLocalBitcasa.ListDir(localrootdir))
+            {
+                string key = akey.name;
+                string dkey = key;
+                const string infstr = "Bitcasa Infinite Drive\\";
+                if (key.IndexOf(localrootdir) == 0)
+                {
+                    dkey = key.Substring(localrootdir.Length);
+                    key = (localrootdir == "I:\\") ? infstr + dkey : dkey;
+                }
+                if (key == "") continue;
+                item olditem;
+                if (difflist.TryGetValue(dkey, out olditem))
+                {
+                    olditem.left = true;
+                    if(save)
+                        BitcasaFileInfo.BitcasaDrive[olditem.key].localinfo = akey;
+                }
+                else
+                {
+                    difflist[dkey] = new item(key, true, false);
+                    if (save)
+                    {
+                        BitcasaFileInfo.BitcasaDrive["\\" + key] = new BitcasaFileInfo();
+                        BitcasaFileInfo.BitcasaDrive["\\" + key].localinfo = akey;
+                    }
+                }
+            }
+            diffItemList.Clear();
+            foreach (KeyValuePair<string, item> pair in difflist)
+            {
+                diffItemList.Add(
+                    ((pair.Value.left) ? "L" : " ") +
+                    ((pair.Value.right) ? "R" : " ") +
+                    " "+
+                    pair.Key);
+            }
+            listBox1.BeginUpdate();
+            listBox1.Items.Clear();
+            foreach (string item in diffItemList)
+            {
+                if (item.IndexOf("LR ") == 0)
+                    continue;
+                listBox1.Items.Add(item);
+            }
+            listBox1.EndUpdate();
+        }
+
+        private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
+        {
+            // Draw the background of the ListBox control for each item.
+            e.DrawBackground();
+            if (e.Index > -1)
+            {
+                if ((e.State & DrawItemState.Selected) != DrawItemState.Selected)
+                {
+                    if (listBox1.Items[e.Index].ToString()[0] != 'L')
+                        e.Graphics.FillRectangle(Brushes.DarkSeaGreen, new RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
+                    if (listBox1.Items[e.Index].ToString()[1] != 'R')
+                        e.Graphics.FillRectangle(Brushes.Salmon, new RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
+                }
+
+                Brush myBrush = new SolidBrush(listBox1.ForeColor);
+
+                e.Graphics.DrawString(listBox1.Items[e.Index].ToString(),
+                    e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
+            }
+            // If the ListBox has focus, draw a focus rectangle around the selected item.
+            e.DrawFocusRectangle();
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            listBox1.BeginUpdate();
+            listBox1.Items.Clear();
+            foreach (string item in diffItemList)
+            {
+                if (item.IndexOf("LR ") == 0)
+                    continue;
+                listBox1.Items.Add(item);
+            }
+            listBox1.EndUpdate();
+        }
+
+        private void button2_Click(object sender, EventArgs e)
+        {
+            listBox1.BeginUpdate();
+            listBox1.Items.Clear();
+            listBox1.Items.AddRange(diffItemList.ToArray<string>());
+            listBox1.EndUpdate();
+        }
+
+    }
+}
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/FormDiff.Designer.cs BitcasaDLL-20140102/bitcasaViewer/FormDiff.Designer.cs
--- BitcasaDLL-20131231/bitcasaViewer/FormDiff.Designer.cs	1970-01-01 09:00:00.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/FormDiff.Designer.cs	2014-01-02 03:04:10.000000000 +0900
@@ -0,0 +1,125 @@
+﻿namespace bitcasaViewer
+{
+    partial class FormDiff
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.listBox1 = new System.Windows.Forms.ListBox();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.button1 = new System.Windows.Forms.Button();
+            this.button2 = new System.Windows.Forms.Button();
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // listBox1
+            // 
+            this.listBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.listBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
+            this.listBox1.FormattingEnabled = true;
+            this.listBox1.Location = new System.Drawing.Point(0, 40);
+            this.listBox1.Name = "listBox1";
+            this.listBox1.Size = new System.Drawing.Size(525, 420);
+            this.listBox1.TabIndex = 0;
+            this.listBox1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.listBox1_DrawItem);
+            // 
+            // panel1
+            // 
+            this.panel1.Controls.Add(this.label2);
+            this.panel1.Controls.Add(this.label1);
+            this.panel1.Controls.Add(this.button2);
+            this.panel1.Controls.Add(this.button1);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
+            this.panel1.Location = new System.Drawing.Point(0, 0);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(525, 34);
+            this.panel1.TabIndex = 1;
+            // 
+            // button1
+            // 
+            this.button1.Location = new System.Drawing.Point(12, 8);
+            this.button1.Name = "button1";
+            this.button1.Size = new System.Drawing.Size(75, 23);
+            this.button1.TabIndex = 0;
+            this.button1.Text = "Diff";
+            this.button1.UseVisualStyleBackColor = true;
+            this.button1.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // button2
+            // 
+            this.button2.Location = new System.Drawing.Point(107, 8);
+            this.button2.Name = "button2";
+            this.button2.Size = new System.Drawing.Size(75, 23);
+            this.button2.TabIndex = 1;
+            this.button2.Text = "All";
+            this.button2.UseVisualStyleBackColor = true;
+            this.button2.Click += new System.EventHandler(this.button2_Click);
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(207, 8);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(35, 12);
+            this.label1.TabIndex = 2;
+            this.label1.Text = "label1";
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(207, 20);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(35, 12);
+            this.label2.TabIndex = 3;
+            this.label2.Text = "label2";
+            // 
+            // FormDiff
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(525, 460);
+            this.Controls.Add(this.panel1);
+            this.Controls.Add(this.listBox1);
+            this.Name = "FormDiff";
+            this.Text = "Diff";
+            this.panel1.ResumeLayout(false);
+            this.panel1.PerformLayout();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.ListBox listBox1;
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Button button1;
+        private System.Windows.Forms.Button button2;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label1;
+    }
+}
\ No newline at end of file
diff -ruN --strip-trailing-cr BitcasaDLL-20131231/bitcasaViewer/FormDiff.resx BitcasaDLL-20140102/bitcasaViewer/FormDiff.resx
--- BitcasaDLL-20131231/bitcasaViewer/FormDiff.resx	1970-01-01 09:00:00.000000000 +0900
+++ BitcasaDLL-20140102/bitcasaViewer/FormDiff.resx	2014-01-02 03:03:16.000000000 +0900
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
