public void internalPublish(PublishMessage msg) {
    final AbstractMessage.QOSType qos = msg.getQos();
    final String topic = msg.getTopicName();
    LOG.info("embedded PUBLISH on topic <{}> with QoS {}", topic, qos);

    String guid = null;
    IMessagesStore.StoredMessage toStoreMsg = asStoredMessage(msg);
    toStoreMsg.setClientID("BROKER_SELF");
    toStoreMsg.setMessageID(1);
    if (qos == AbstractMessage.QOSType.EXACTLY_ONCE) { // QoS2
      guid = m_messagesStore.storePublishForFuture(toStoreMsg);
    }
    route2Subscribers(toStoreMsg);

    if (!msg.isRetainFlag()) {
      return;
    }
    if (qos == AbstractMessage.QOSType.MOST_ONE || !msg.getPayload().hasRemaining()) {
      // QoS == 0 && retain => clean old retained
      m_messagesStore.cleanRetained(topic);
      return;
    }
    if (guid == null) {
      // before wasn't stored
      guid = m_messagesStore.storePublishForFuture(toStoreMsg);
    }
    m_messagesStore.storeRetained(topic, guid);
  }
 private static IMessagesStore.StoredMessage asStoredMessage(PublishMessage msg) {
   IMessagesStore.StoredMessage stored =
       new IMessagesStore.StoredMessage(
           msg.getPayload().array(), msg.getQos(), msg.getTopicName());
   stored.setRetained(msg.isRetainFlag());
   stored.setMessageID(msg.getMessageID());
   return stored;
 }
  /** Specialized version to publish will testament message. */
  private void forwardPublishWill(WillMessage will, String clientID) {
    // it has just to publish the message downstream to the subscribers
    // NB it's a will publish, it needs a PacketIdentifier for this conn, default to 1
    Integer messageId = null;
    if (will.getQos() != AbstractMessage.QOSType.MOST_ONE) {
      messageId = m_messagesStore.nextPacketID(clientID);
    }

    IMessagesStore.StoredMessage tobeStored = asStoredMessage(will);
    tobeStored.setClientID(clientID);
    tobeStored.setMessageID(messageId);
    route2Subscribers(tobeStored);
  }