private async Task <LoadAllDepartments.Response> GetAllDepartmentsInternal()
        {
            using (var context = this.contextFactory())
            {
                var arcEmployees = new CspEmployeeQuery(context).Get();

                var allDepartments = await context
                                     .Department
                                     .Where(x => (x.IsDelete != true) && (x.CompanyId == this.configuration.CompanyId))
                                     .GroupJoin(arcEmployees, d => d.ChiefId, e => e.Id, this.mapDepartment)
                                     .GroupJoin(arcEmployees, d => d.DepartmentId, e => e.DepartmentId.ToString(), this.countEmployees)
                                     .ToListAsync();

                var head = allDepartments.FirstOrDefault(x => x.Info.IsHeadDepartment && (x.Info.Abbreviation == this.configuration.HeadDepartmentAbbreviation));

                if (head == null)
                {
                    return(new LoadAllDepartments.Response(new DepartmentInfo[0]));
                }

                var processedIds = new HashSet <string>()
                {
                    head.Info.DepartmentId
                };
                var tree = new DepartmentsTreeNode(head.Info, head.PeopleCount, this.CreateTree(allDepartments, head.Info.DepartmentId, processedIds));

                var departments = tree.AsEnumerable().Where(x => x.CountAllEmployees() != 0).Select(x => x.DepartmentInfo).ToList();

                return(new LoadAllDepartments.Response(departments));
            }
        }
        /// <param name="departmentId">Node for which descandants are requested</param>
        /// <param name="processedIds">a hashset with processed department ids to prevent stackoverflow</param>
        /// <param name="allDepartments">all possible departments</param>
        private List <DepartmentsTreeNode> CreateTree(IReadOnlyCollection <DepartmentInfoWithPeopleCount> allDepartments,
                                                      string departmentId,
                                                      HashSet <string> processedIds)
        {
            var childrenDepartments = allDepartments
                                      .Where(x => (x.Info.ParentDepartmentId == departmentId) && !processedIds.Contains(x.Info.DepartmentId))
                                      .ToList();

            processedIds.UnionWith(childrenDepartments.Select(x => x.Info.DepartmentId));

            var children = new List <DepartmentsTreeNode>();

            foreach (var department in childrenDepartments)
            {
                var child = new DepartmentsTreeNode(department.Info, department.PeopleCount, this.CreateTree(allDepartments, department.Info.DepartmentId, processedIds));
                children.Add(child);
            }

            return(children);
        }