class PushServer {
    private static final Logger LOG = LoggerFactory.getLogger(PushServer.class);
    protected static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
    public interface PushMessageType {
        int PUSH_MESSAGE_TYPE_NORMAL = 0;
        int PUSH_MESSAGE_TYPE_VOIP_INVITE = 1;
        int PUSH_MESSAGE_TYPE_VOIP_BYE = 2;
        int PUSH_MESSAGE_TYPE_FRIEND_REQUEST = 3;
        int PUSH_MESSAGE_TYPE_VOIP_ANSWER = 4;
        int PUSH_MESSAGE_TYPE_RECALLED = 5;
        int PUSH_MESSAGE_TYPE_DELETED = 6;
    }

    private static PushServer INSTANCE = new PushServer();
    private ISessionsStore sessionsStore;
    private static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*5);

    private String androidPushServerUrl;
    private String iOSPushServerUrl;

    private PushServer() {
    }

    public static PushServer getServer() {
        return INSTANCE;
    }

    public void init(IConfig config, ISessionsStore sessionsStore) {
        this.sessionsStore = sessionsStore;
        this.androidPushServerUrl = config.getProperty(PUSH_ANDROID_SERVER_ADDRESS);
        this.iOSPushServerUrl = config.getProperty(PUSH_IOS_SERVER_ADDRESS);
    }

    public void pushMessage(PushMessage pushMessage, String deviceId, String pushContent) {
        LOG.info("try to delivery push diviceId = {}, conversationType = {}, pushContent = {}", deviceId, pushMessage.convType, pushContent);
        executorService.execute(() ->{
                try {
                    pushMessageInternel(pushMessage, deviceId, pushContent);
                } catch (Exception e) {
                    e.printStackTrace();
                    Utility.printExecption(LOG, e, IMExceptionEvent.EventType.PUSH_SERVER_Exception);
                }
            });
    }

    private void pushMessageInternel(PushMessage pushMessage, String deviceId, String pushContent) {<FILL_FUNCTION_BODY>}
}

        if (pushMessage.pushMessageType == PushMessageType.PUSH_MESSAGE_TYPE_NORMAL && StringUtil.isNullOrEmpty(pushContent)) {
            LOG.info("push content empty, deviceId {}", deviceId);
            return;
        }

        MemorySessionStore.Session session = sessionsStore.getSession(deviceId);
        int badge = session.getUnReceivedMsgs();
        if (badge <= 0) {
            badge = 1;
        }
        if (StringUtil.isNullOrEmpty(session.getDeviceToken())) {
            LOG.warn("Device token is empty for device {}", deviceId);
            return;
        }

        pushMessage.packageName = session.getAppName();
        pushMessage.pushType = session.getPushType();
        pushMessage.pushContent = pushContent;
        pushMessage.deviceToken = session.getDeviceToken();
        pushMessage.unReceivedMsg = badge;
        pushMessage.userId = session.getUsername();
        if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS ||
            session.getPlatform() == ProtoConstants.Platform.Platform_iPad ||
            session.getPlatform() == ProtoConstants.Platform.Platform_Android ||
            session.getPlatform() == ProtoConstants.Platform.Platform_APad ||
            session.getPlatform() == ProtoConstants.Platform.Platform_Harmony ||
            session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad
        ) {
            String url = androidPushServerUrl;
            if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_iPad) {
                url = iOSPushServerUrl;
                pushMessage.voipDeviceToken = session.getVoipDeviceToken();
            }
            HttpUtils.httpJsonPost(url, gson.toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push);
        } else {
            LOG.info("Not mobile platform {}", session.getPlatform());
        }
    
<no_super_class>