public OfflineMessage addMessage(Message message) {
        if (message == null) {
            Log.trace( "Not storing null message." );
            return null;
        }
        if(!shouldStoreMessage(message)) {
            Log.trace( "Not storing message, as 'should store' returned false." );
            return null;
        }
        JID recipient = message.getTo();
        String username = recipient.getNode();
        // If the username is null (such as when an anonymous user), don't store.
        if (username == null || !(UserManager.getInstance().isRegisteredUser(recipient, false) || UserManager.isPotentialFutureLocalUser(recipient))) {
            Log.trace( "Not storing message for which the recipient ({}) is not a registered local user.", recipient );
            return null;
        }

        long messageID = SequenceManager.nextID(JiveConstants.OFFLINE);

        // Get the message in XML format.
        String msgXML = message.getElement().asXML();

        Connection con = null;
        PreparedStatement pstmt = null;
        OfflineMessage offlineMessage = null;
        try {
            con = DbConnectionManager.getConnection();
            pstmt = con.prepareStatement(INSERT_OFFLINE);

            Date creationDate = new java.util.Date();
            pstmt.setString(1, username);
            pstmt.setLong(2, messageID);
            pstmt.setString(3, StringUtils.dateToMillis(creationDate));
            pstmt.setInt(4, msgXML.length());
            pstmt.setString(5, msgXML);
            pstmt.executeUpdate();

            offlineMessage = new OfflineMessage(creationDate, message.getElement());
        }
        catch (Exception e) {
            Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
            return null;
        }
        finally {
            DbConnectionManager.closeConnection(pstmt, con);
        }

        // Update the cached size if it exists.
        if (sizeCache.containsKey(username)) {
            int size = sizeCache.get(username);
            size += msgXML.length();
            sizeCache.put(username, size);
        }
        return offlineMessage;
    }
Adds a message to this message store. Messages will be stored and made
available for later delivery.

Note that certain messages are ignored by this implementation, for example, messages that are carbon copies,
have 'no-store' hints, or for which the intended recipient is not a local user. When a message is discarded for
reasons like these, this method will return 'null'.

@param message the message to store.
@return OfflineMessage when data was stored, otherwise null.
xmppserver/src/main/java/org/jivesoftware/openfire/OfflineMessageStore.java