// This function updates a folder tree based on the
        // changes received from the server in the response.
        public void UpdateFolderTree(Folder rootFolder)
        {
            rootFolder.LastSyncTime = DateTime.Now.ToUniversalTime();

            try
            {
                // Get sync key
                XmlNode syncKeyNode = responseXml.SelectSingleNode(".//folderhierarchy:SyncKey", xmlNsMgr);
                rootFolder.SyncKey = syncKeyNode.InnerText;

                // Process adds (new folders) first
                XmlNodeList addNodes = responseXml.SelectNodes(".//folderhierarchy:Add", xmlNsMgr);
                foreach (XmlNode addNode in addNodes)
                {
                    XmlNode nameNode     = addNode.SelectSingleNode(".//folderhierarchy:DisplayName", xmlNsMgr);
                    XmlNode serverIdNode = addNode.SelectSingleNode(".//folderhierarchy:ServerId", xmlNsMgr);
                    XmlNode parentIdNode = addNode.SelectSingleNode(".//folderhierarchy:ParentId", xmlNsMgr);
                    XmlNode typeNode     = addNode.SelectSingleNode(".//folderhierarchy:Type", xmlNsMgr);

                    rootFolder.AddFolder(nameNode.InnerText, serverIdNode.InnerText, parentIdNode.InnerText,
                                         (Folder.FolderType)XmlConvert.ToInt32(typeNode.InnerText));
                }

                // Then process deletes
                XmlNodeList deleteNodes = responseXml.SelectNodes(".//folderhierarchy:Delete", xmlNsMgr);
                foreach (XmlNode deleteNode in deleteNodes)
                {
                    XmlNode serverIdNode = deleteNode.SelectSingleNode(".//folderhierarchy:ServerId", xmlNsMgr);

                    Folder removeFolder = rootFolder.FindFolderById(serverIdNode.InnerText);
                    removeFolder.Remove();
                }

                // Finally process any updates to existing folders
                XmlNodeList updateNodes = responseXml.SelectNodes(".//folderhierarchy:Update", xmlNsMgr);
                foreach (XmlNode updateNode in updateNodes)
                {
                    XmlNode nameNode     = updateNode.SelectSingleNode(".//folderhierarchy:DisplayName", xmlNsMgr);
                    XmlNode serverIdNode = updateNode.SelectSingleNode(".//folderhierarchy:ServerId", xmlNsMgr);
                    XmlNode parentIdNode = updateNode.SelectSingleNode(".//folderhierarchy:ParentId", xmlNsMgr);
                    XmlNode typeNode     = updateNode.SelectSingleNode(".//folderhierarchy:Type", xmlNsMgr);

                    Folder updateFolder = rootFolder.FindFolderById(serverIdNode.InnerText);
                    Folder updateParent = rootFolder.FindFolderById(parentIdNode.InnerText);

                    updateFolder.Update(nameNode.InnerText, updateParent,
                                        (Folder.FolderType)XmlConvert.ToInt32(typeNode.InnerText));
                }
            }
            catch (Exception e)
            {
                // Rather than attempting to recover, reset sync key
                // and empty folders. The next FolderSync should
                // re-sync folders.
                rootFolder.SyncKey = "0";
                rootFolder.RemoveAllSubFolders();
            }

            rootFolder.SaveFolderInfo();
        }