public void AddRecruitedMember(Character newMember, Character recruiterMember)
        {
            IsActive.ThrowIfFalse(ErrorCodes.AccessDenied);
            IsAvailableFreeSlot.ThrowIfFalse(ErrorCodes.CorporationMaxMembersReached);

            var oldCorporation = newMember.GetCorporation();

            //this protects the alliance board member complication and default corp situation
            var role = GetRoleFromSql(newMember);

            role.ThrowIfNotEqual(CorporationRole.NotDefined, ErrorCodes.MemberHasRolesError);

            CorporationManager.IsJoinAllowed(newMember).ThrowIfFalse(ErrorCodes.CorporationChangeTooOften);

            AddMember(newMember, CorporationRole.NotDefined, oldCorporation);
            oldCorporation.RemoveMember(newMember);

            newMember.GetCorporationApplications().DeleteAll();

            _channelManager.LeaveChannel(oldCorporation.ChannelName, newMember);
            _channelManager.JoinChannel(ChannelName, newMember, GetMemberRole(newMember));

            Transaction.Current.OnCommited(() =>
            {
                CorporationManager.InformCorporationMemberTransferred(oldCorporation, this, newMember);

                newMember.GetPlayerRobotFromZone()?.UpdateCorporationOnZone(Eid);
                var info = new Dictionary <string, object>
                {
                    { k.@from, oldCorporation.Eid },
                    { k.to, Eid },
                    { k.characterID, newMember.Id },
                };

                ZoneManager.Value.Zones.ForEach(z => z.UpdateCorporation(CorporationCommand.TransferMember, info));

                CorporationData.RemoveFromCache(oldCorporation.Eid);
                CorporationData.RemoveFromCache(Eid);

                if (_characterProfiles is CachedReadOnlyRepository <int, CharacterProfile> c)
                {
                    c.Remove(newMember.Id);
                }
            });
        }
        public void InformCorporationMemberTransferred(Corporation oldCorporation, Corporation newCorporation, Character member, Character kicker)
        {
            var data = new Dictionary <string, object>
            {
                { k.@from, oldCorporation.Eid },
                { k.to, newCorporation.Eid },
                { k.memberID, member.Id }
            };

            if (kicker.Id > 0)
            {
                data.Add(k.kickedBy, kicker.Id);
            }

            if (newCorporation is PrivateCorporation)
            {
                Message.Builder.SetCommand(Commands.CorporationMemberTransferred)
                .WithData(data)
                .ToCorporation(newCorporation)
                .Send();
            }
            else
            {
                Message.Builder.SetCommand(Commands.CorporationMemberTransferred)
                .WithData(data)
                .ToCharacter(member)
                .Send();
            }

            if (oldCorporation is PrivateCorporation)
            {
                Message.Builder.SetCommand(Commands.CorporationMemberTransferred)
                .WithData(data)
                .ToCorporation(oldCorporation)
                .Send();
            }

            CorporationData.RemoveFromCache(newCorporation.Eid);
            CorporationData.RemoveFromCache(oldCorporation.Eid);
        }
        public void TakeOverCeoRole(VolunteerCEO volunteerCEO)
        {
            Logger.Info($"takeover for {volunteerCEO}");

            var corporation = volunteerCEO.character.GetPrivateCorporationOrThrow();

            using (var scope = Db.CreateTransaction())
            {
                try
                {
                    if (corporation.Eid != volunteerCEO.corporation.Eid)
                    {
                        return;
                    }

                    var volunteerCharacter = volunteerCEO.character;

                    var role    = corporation.GetMemberRole(volunteerCharacter);
                    var oldRole = role;

                    var currentCEO = corporation.CEO;
                    if (currentCEO == volunteerCEO.character || !role.HasFlag(CorporationRole.DeputyCEO) || role.HasFlag(CorporationRole.CEO))
                    {
                        return;
                    }

                    //check member count again, possible downgrade could've happened
                    var desiredCEOMaxMembers = corporation.GetMaxmemberByCharacter(volunteerCharacter);
                    if (corporation.Members.Length > desiredCEOMaxMembers)
                    {
                        return;
                    }

                    role = role.SetRole(CorporationRole.CEO);
                    role = role.ClearRole(CorporationRole.DeputyCEO);

                    corporation.SetMemberRole(volunteerCharacter, role);
                    corporation.WriteRoleHistory(volunteerCEO.character, volunteerCEO.character, role, oldRole);

                    _channelManager.SetMemberRole(corporation.ChannelName, volunteerCEO.character, role);

                    //old ceo

                    var currentCeoRole    = corporation.GetMemberRole(currentCEO);
                    var oldCurrentCeoRole = currentCeoRole;

                    currentCeoRole = currentCeoRole.ClearRole(CorporationRole.CEO);
                    currentCeoRole = currentCeoRole.SetRole(CorporationRole.DeputyCEO);

                    corporation.SetMemberRole(currentCEO, currentCeoRole);
                    corporation.WriteRoleHistory(currentCEO, currentCEO, currentCeoRole, oldCurrentCeoRole);

                    _channelManager.SetMemberRole(corporation.ChannelName, currentCEO, currentCeoRole);
                    CorporationData.RemoveFromCache(corporation.Eid);

                    Logger.Info($"{volunteerCharacter} took over CEO for {currentCEO} at corporationeid:{corporation.Eid}");

                    _volunteerCEORepository.Delete(volunteerCEO);

                    //ok inform
                    Transaction.Current.OnCompleted(c =>
                    {
                        SendVolunteerStatusToMembers(volunteerCEO);
                    });

                    scope.Complete();
                }
                catch (Exception ex)
                {
                    Logger.Exception(ex);
                }
            }
        }