public void Move(uint folderId, uint toFolderId)
        {
            var exp = SimpleUserFoldersTreeExp.CreateBuilder()
                      .SetParent(folderId)
                      .Build();

            var subFolders = Get(exp)
                             .ToDictionary(r => r.FolderId, r => r.Level);

            if (!subFolders.Any())
            {
                return;
            }

            var query = new SqlDelete(UserFolderTreeTable.TABLE_NAME)
                        .Where(Exp.In(UserFolderTreeTable.Columns.FolderId, subFolders.Keys) &
                               !Exp.In(UserFolderTreeTable.Columns.ParentId, subFolders.Keys));

            // ReSharper disable once NotAccessedVariable
            var result = Db.ExecuteNonQuery(query);

            foreach (var subFolder in subFolders)
            {
                var subQuery = new SqlQuery(UserFolderTreeTable.TABLE_NAME)
                               .Select(subFolder.Key.ToString(CultureInfo.InvariantCulture),
                                       UserFolderTreeTable.Columns.ParentId,
                                       string.Format("{0} + {1}", _levelUp, subFolder.Value.ToString(CultureInfo.InvariantCulture)))
                               .Where(UserFolderTreeTable.Columns.FolderId, toFolderId);

                var insertQuery = new SqlInsert(UserFolderTreeTable.TABLE_NAME, true)
                                  .InColumns(UserFolderTreeTable.Columns.FolderId,
                                             UserFolderTreeTable.Columns.ParentId,
                                             UserFolderTreeTable.Columns.Level)
                                  .Values(subQuery);

                // ReSharper disable once RedundantAssignment
                result = Db.ExecuteNonQuery(insertQuery);
            }
        }
        public void Delete(uint folderId)
        {
            var affectedIds = new List <int>();

            using (var db = new DbManager(Defines.CONNECTION_STRING_NAME, Defines.RecalculateFoldersTimeout))
            {
                var daoFactory = new DaoFactory(db);

                var userFolderXmailDao = daoFactory.CreateUserFolderXMailDao(Tenant, User);

                var userFolderTreeDao = daoFactory.CreateUserFolderTreeDao(Tenant, User);

                var userFolderDao = daoFactory.CreateUserFolderDao(Tenant, User);

                var folder = userFolderDao.Get(folderId);
                if (folder == null)
                {
                    return;
                }

                using (var tx = daoFactory.DbManager.BeginTransaction(IsolationLevel.ReadUncommitted))
                {
                    //Find folder sub-folders
                    var expTree = SimpleUserFoldersTreeExp.CreateBuilder()
                                  .SetParent(folder.Id)
                                  .Build();

                    var removeFolderIds = userFolderTreeDao.Get(expTree)
                                          .ConvertAll(f => f.FolderId);

                    if (!removeFolderIds.Contains(folderId))
                    {
                        removeFolderIds.Add(folderId);
                    }

                    //Remove folder with subfolders
                    var expFolders = SimpleUserFoldersExp.CreateBuilder(Tenant, User)
                                     .SetIds(removeFolderIds)
                                     .Build();

                    userFolderDao.Remove(expFolders);

                    //Remove folder tree info
                    expTree = SimpleUserFoldersTreeExp.CreateBuilder()
                              .SetIds(removeFolderIds)
                              .Build();

                    userFolderTreeDao.Remove(expTree);

                    //Move mails to trash
                    foreach (var id in removeFolderIds)
                    {
                        var listMailIds = userFolderXmailDao.GetMailIds(id);

                        if (!listMailIds.Any())
                        {
                            continue;
                        }

                        affectedIds.AddRange(listMailIds);

                        //Move mails to trash
                        Factory.MessageEngine.SetFolder(daoFactory, listMailIds, FolderType.Trash);

                        //Remove listMailIds from 'mail_user_folder_x_mail'
                        userFolderXmailDao.Remove(listMailIds);
                    }

                    tx.Commit();
                }

                userFolderDao.RecalculateFoldersCount(folder.ParentId);
            }

            if (!FactoryIndexer <MailWrapper> .Support || !affectedIds.Any())
            {
                return;
            }

            var data = new MailWrapper
            {
                Folder = (byte)FolderType.Trash
            };

            Factory.IndexEngine.Update(data, s => s.In(m => m.Id, affectedIds.ToArray()), wrapper => wrapper.Unread);
        }