public static Message parseMessage(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
        ParserUtils.assertAtStartTag(parser);
        assert (parser.getName().equals(Message.ELEMENT));

        XmlEnvironment messageXmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment);
        final int initialDepth = parser.getDepth();
        Message message = new Message();
        message.setStanzaId(parser.getAttributeValue("", "id"));
        message.setTo(ParserUtils.getJidAttribute(parser, "to"));
        message.setFrom(ParserUtils.getJidAttribute(parser, "from"));
        String typeString = parser.getAttributeValue("", "type");
        if (typeString != null) {
            message.setType(Message.Type.fromString(typeString));
        }
        String language = ParserUtils.getXmlLang(parser);
        message.setLanguage(language);

        // Parse sub-elements. We include extra logic to make sure the values
        // are only read once. This is because it's possible for the names to appear
        // in arbitrary sub-elements.
        String thread = null;
        outerloop: while (true) {
            int eventType = parser.next();
            switch (eventType) {
            case XmlPullParser.START_TAG:
                String elementName = parser.getName();
                String namespace = parser.getNamespace();
                switch (elementName) {
                case "subject":
                    String xmlLangSubject = ParserUtils.getXmlLang(parser);
                    String subject = parseElementText(parser);

                    if (message.getSubject(xmlLangSubject) == null) {
                        message.addSubject(xmlLangSubject, subject);
                    }
                    break;
                case "thread":
                    if (thread == null) {
                        thread = parser.nextText();
                    }
                    break;
                case "error":
                    message.setError(parseError(parser, messageXmlEnvironment));
                    break;
                 default:
                    PacketParserUtils.addExtensionElement(message, parser, elementName, namespace, messageXmlEnvironment);
                    break;
                }
                break;
            case XmlPullParser.END_TAG:
                if (parser.getDepth() == initialDepth) {
                    break outerloop;
                }
                break;
            }
        }

        message.setThread(thread);

        // TODO check for duplicate body elements. This means we need to check for duplicate xml:lang pairs and for
        // situations where we have a body element with an explicit xml lang set and once where the value is inherited
        // and both values are equal.

        return message;
    }
public static Message parseMessage ( XmlPullParser parser , XmlEnvironment outerXmlEnvironment ) throws XmlPullParserException , IOException , SmackParsingException { ParserUtils . assertAtStartTag ( parser ) ; assert ( parser . getName ( ) . equals ( Message . ELEMENT ) ) ; XmlEnvironment messageXmlEnvironment = XmlEnvironment . from ( parser , outerXmlEnvironment ) ; final int initialDepth = parser . getDepth ( ) ; Message message = new Message ( ) ; message . setStanzaId ( parser . getAttributeValue ( "" , "id" ) ) ; message . setTo ( ParserUtils . getJidAttribute ( parser , "to" ) ) ; message . setFrom ( ParserUtils . getJidAttribute ( parser , "from" ) ) ; String typeString = parser . getAttributeValue ( "" , "type" ) ; if ( typeString != null ) { message . setType ( Message . Type . fromString ( typeString ) ) ; } String language = ParserUtils . getXmlLang ( parser ) ; message . setLanguage ( language ) ; String thread = null ; outerloop : while ( true ) { int eventType = parser . next ( ) ; switch ( eventType ) { case XmlPullParser . START_TAG : String elementName = parser . getName ( ) ; String namespace = parser . getNamespace ( ) ; switch ( elementName ) { case "subject" : String xmlLangSubject = ParserUtils . getXmlLang ( parser ) ; String subject = parseElementText ( parser ) ; if ( message . getSubject ( xmlLangSubject ) == null ) { message . addSubject ( xmlLangSubject , subject ) ; } break ; case "thread" : if ( thread == null ) { thread = parser . nextText ( ) ; } break ; case "error" : message . setError ( parseError ( parser , messageXmlEnvironment ) ) ; break ; default : PacketParserUtils . addExtensionElement ( message , parser , elementName , namespace , messageXmlEnvironment ) ; break ; } break ; case XmlPullParser . END_TAG : if ( parser . getDepth ( ) == initialDepth ) { break outerloop ; } break ; } } message . setThread ( thread ) ; return message ; }
Parses a message packet.

@param parser the XML parser, positioned at the start of a message packet.
@param outerXmlEnvironment the outer XML environment (optional).
@return a Message packet.
@throws XmlPullParserException
@throws IOException
@throws SmackParsingException