class GroupHandler<T> extends IMHandler<T> {
    protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content) {
        sendGroupNotification(fromUser, targetId, lines, content, null);
    }

    protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content, Collection<String> toUsers) {<FILL_FUNCTION_BODY>}

    protected List<String> getMemberIdList(List<WFCMessage.GroupMember> groupMembers) {
        List<String> out = new ArrayList<>();
        if (groupMembers != null) {
            for (WFCMessage.GroupMember gm : groupMembers
                 ) {
                out.add(gm.getMemberId());
            }
        }
        return out;
    }
}

        if (lines == null) {
            lines = new ArrayList<>();
        } else {
            lines = new ArrayList<>(lines);
        }

        if (lines.isEmpty()) {
            lines.add(0);
        }

        for (int line : lines) {
            long timestamp = System.currentTimeMillis();
            WFCMessage.Message.Builder builder = WFCMessage.Message.newBuilder().setContent(content).setServerTimestamp(timestamp);
            builder.setConversation(builder.getConversationBuilder().setType(ProtoConstants.ConversationType.ConversationType_Group).setTarget(targetId).setLine(line));
            builder.setFromUser(fromUser);
            if(toUsers != null && !toUsers.isEmpty()) {
                builder.addAllTo(toUsers);
            }
            try {
                long messageId = MessageShardingUtil.generateId();
                builder.setMessageId(messageId);
                saveAndPublish(fromUser, null, builder.build(), ProtoConstants.RequestSourceType.Request_From_User);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
<methods>public void <init>() ,public abstract cn.wildfirechat.common.ErrorCode action(ByteBuf, java.lang.String, java.lang.String, cn.wildfirechat.proto.ProtoConstants.RequestSourceType, T, io.moquette.spi.impl.Qos1PublishHandler.IMCallback) ,public void afterAction(java.lang.String, java.lang.String, java.lang.String, io.moquette.spi.impl.Qos1PublishHandler.IMCallback) ,public void doHandler(java.lang.String, java.lang.String, java.lang.String, byte[], io.moquette.spi.impl.Qos1PublishHandler.IMCallback, cn.wildfirechat.proto.ProtoConstants.RequestSourceType) ,public static io.moquette.spi.impl.MessagesPublisher getPublisher() ,public static void init(io.moquette.spi.IMessagesStore, io.moquette.spi.ISessionsStore, io.moquette.spi.impl.MessagesPublisher, cn.wildfirechat.server.ThreadPoolExecutorWrapper, io.moquette.server.Server) ,public cn.wildfirechat.common.ErrorCode preAction(java.lang.String, java.lang.String, java.lang.String, io.moquette.spi.impl.Qos1PublishHandler.IMCallback, cn.wildfirechat.proto.ProtoConstants.RequestSourceType) <variables>protected static final Logger LOG,protected static java.lang.String actionName,private Class#RAW dataCls,private static win.liyufan.im.RateLimiter mLimitCounter,protected static io.moquette.server.Server mServer,private static cn.wildfirechat.server.ThreadPoolExecutorWrapper m_imBusinessExecutor,protected static io.moquette.spi.IMessagesStore m_messagesStore,protected static io.moquette.spi.ISessionsStore m_sessionsStore,private java.lang.reflect.Method parseDataMethod,protected static io.moquette.spi.impl.MessagesPublisher publisher