internal GroupAdministrationInfo GetGroupInfo(long groupId)
        {
            lock (this)
            {
                if (_groups.TryGetValue(groupId, out var group))
                {
                    return(group);
                }
            }

            var data = _groupStorage.Storage.GetBlockData(groupId);

            if (data == null)
            {
                return(null);
            }

            var info = new GroupAdministrationInfo(new Unpacker(data));

            lock (this)
            {
                if (_groups.TryGetValue(groupId, out var gr))
                {
                    return(gr);
                }

                _groups[groupId] = info;
            }
            return(info);
        }
        public override void ConsumeFeatureRequest(CommitItems commitItems, Commit commit, FeatureRequest featureRequest, Transaction transaction)
        {
            var accountId = transaction.AccountId;

            if (featureRequest.RequestId == GroupRegistrationRequest.GroupRegistrationRequestId)
            {
                var feature      = transaction.GetFeature <GroupAdministration>(FeatureId);
                var container    = CurrentChain.GetFeatureAccount(accountId).GetOrAddFeatureContainer <GroupAdministrationContainer>(FeatureId);
                var registration = featureRequest as GroupRegistrationRequest;

                var groupid = feature.NewGroupId;
                var group   = new GroupAdministrationInfo(groupid, accountId, transaction.TransactionId, transaction.Timestamp, registration.GroupFlags);

                lock (this)
                    _groups[groupid] = group;
                _groupStorage.Storage.AddEntry(groupid, group.ToByteArray());

                container.AddGroup(groupid);
                commitItems.DirtyAccounts.Add(accountId);
            }
            else if (featureRequest.RequestId == GroupAdministrationRequest.GroupAdministrationRequestId)
            {
                var request = featureRequest as GroupAdministrationRequest;
                var groupId = request.GroupId;
                var group   = GetGroupInfo(groupId);

                group.ConsumeGroupAdministrationRequest(transaction, request, out var dirtyGroupAccounts);
                commit.DirtyIds.Add(groupId);

                foreach (var added in dirtyGroupAccounts.AddedAccounts)
                {
                    var container = CurrentChain.GetFeatureAccount(added).GetOrAddFeatureContainer <GroupAdministrationContainer>(FeatureId);
                    container.AddGroup(groupId);
                    commitItems.DirtyAccounts.Add(added);
                }

                foreach (var removed in dirtyGroupAccounts.RemovedAccounts)
                {
                    var container = CurrentChain.GetFeatureAccount(removed).GetOrAddFeatureContainer <GroupAdministrationContainer>(FeatureId);
                    container.RemoveGroup(groupId);
                    commitItems.DirtyAccounts.Add(removed);
                }
            }
        }