public async Task <int> Handle(PrivateSession session, FieldPhaseInfoUpdateRequest request, Func <PrivateConnection> connectionFactory)
        {
            var requestFields = request.Items.Select(x => x.Field).ToList();
            var guidMappings  = (await session.CallAsync(FieldRequest.GetFields().Select(FieldProperty.Id).WhereField(requestFields)))
                                .ToDictionary(entry => entry.Value.Guid, entry => entry.Key);

            var affectedPhases = new Dictionary <HrbcField, IEnumerable <FieldPhaseInfo> >();

            for (var i = 0; i < guidMappings.Values.Count; i += FieldPhaseInfoReadRequestBatchSize)
            {
                int range = Math.Min(FieldPhaseInfoReadRequestBatchSize, guidMappings.Values.Count - i);
                affectedPhases = affectedPhases.Concat(await session.CallAsync(FieldPhaseInfoReadRequest.Builder.Fields(requestFields.Skip(i).Take(range)).Build()))
                                 .ToDictionary(x => x.Key, x => x.Value);
            }

            var requestJsonObject = new Dictionary <Guid, Dictionary <Guid, Json.FieldPhaseInfoUpdateRequestEntry> >();

            foreach (var item in request.Items)
            {
                Dictionary <ulong, AccessType> permissionMapping = (item.OptionIdToAccessTypeMap != null && item.OptionIdToAccessTypeMap.Any()) ?
                                                                   item.OptionIdToAccessTypeMap.ToDictionary(x => x.Key, x => x.Value) :
                                                                   item.OptionAliasToAccessTypeMap.ToDictionary(x => GetOptionIdByAlias(x.Key, session), x => x.Value);
                FieldPhaseInfo targetPhase = affectedPhases[item.Field].Single(phase => string.Equals(phase.Group.Name, item.AclGroupName, StringComparison.OrdinalIgnoreCase));

                permissionMapping = targetPhase.PhasePermission.ToDictionary(x => x.Key, x => permissionMapping.ContainsKey(x.Key) ? permissionMapping[x.Key] : x.Value);

                var guidMapping = guidMappings.Where(x => x.Value == item.Field).ToDictionary(x => x.Key, x => x.Value);

                requestJsonObject = requestJsonObject.Concat(ComposeJsonRequestObject(guidMapping, permissionMapping, item.Permission, targetPhase)).ToDictionary(x => x.Key, x => x.Value);
            }


            for (var i = 0; i < requestJsonObject.Values.Count; i += FieldUpdateRequestBatchSize)
            {
                using (var connection = connectionFactory().ApiName("acl/field-phase-info").Method(PrivateConnectionMethod.Update))
                {
                    try
                    {
                        int range = Math.Min(FieldUpdateRequestBatchSize, requestJsonObject.Values.Count - i);
                        var batch = requestJsonObject.Skip(i).Take(range).ToDictionary(x => x.Key, x => x.Value);
                        using (var response = await connection.SendAsync(batch))
                        {
                            if (response.Code != SuccessResponseCode)
                            {
                                return(response.Code);
                            }
                        }
                    }
                    catch (ConnectionResponseException e)
                    {
                        throw e.ToRequestException("ACL Group List Update failed", request);
                    }
                }
            }
            return(SuccessResponseCode);
        }
 private Dictionary <Guid, Dictionary <Guid, Json.FieldPhaseInfoUpdateRequestEntry> > ComposeJsonRequestObject(Dictionary <Guid, HrbcField> guidMapping,
                                                                                                               Dictionary <ulong, AccessType> permissionMapping, AccessType?generalPermission, FieldPhaseInfo targetPhase)
 {
     return(guidMapping.ToDictionary(item => item.Key,
                                     item => new Dictionary <Guid, Json.FieldPhaseInfoUpdateRequestEntry>
     {
         [targetPhase.Group.Guid] = new Json.FieldPhaseInfoUpdateRequestEntry
         {
             IsDefined = targetPhase.IsDefined ? 1 : 0,
             Name = targetPhase.Group.Name,
             Permission = generalPermission.GetValueOrDefault(targetPhase.Permission),
             Type = targetPhase.Group.Type.GetValueOrDefault(AclGroupType.Root),
             PhasePermission = permissionMapping == null || !permissionMapping.Any()
                     ? targetPhase.PhasePermission.ToDictionary(entry => entry.Key, entry => new Json.FieldPhaseInfoUpdateResponsePhaseEntry
             {
                 Permission = entry.Value
             })
                     : permissionMapping.ToDictionary(entry => entry.Key, entry => new Json.FieldPhaseInfoUpdateResponsePhaseEntry
             {
                 Permission = entry.Value
             }),
         }
     }));
 }