--- /home/cmeng/source/smack/Smack/trunk/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java	2019-09-26 05:45:29.000000000 
+++ /home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java	2019-10-19 09:30:09.000000000 
@@ -37,12 +37,13 @@
 import org.jivesoftware.smack.packet.IQ;
 import org.jivesoftware.smack.packet.Message;
 import org.jivesoftware.smack.packet.Nonza;
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.packet.Stanza;
 import org.jivesoftware.smack.packet.StanzaError;
+import org.jivesoftware.smack.packet.XmlEnvironment;
 import org.jivesoftware.smack.util.CloseableUtil;
 import org.jivesoftware.smack.util.PacketParserUtils;
 import org.jivesoftware.smack.xml.XmlPullParser;
 
 import org.igniterealtime.jbosh.AbstractBody;
 import org.igniterealtime.jbosh.BOSHClient;
@@ -363,12 +364,13 @@
         client.addBOSHClientRequestListener(new BOSHClientRequestListener() {
             @Override
             public void requestSent(BOSHMessageEvent event) {
                 if (event.getBody() != null) {
                     try {
                         writer.write(event.getBody().toXML());
+                        writer.flush();
                     } catch (Exception e) {
                         // Ignore
                     }
                 }
             }
         });
@@ -397,17 +399,18 @@
     @Override
     protected void afterSaslAuthenticationSuccess()
                     throws NotConnectedException, InterruptedException, SmackWrappedException {
         // XMPP over BOSH is unusual when it comes to SASL authentication: Instead of sending a new stream open, it
         // requires a special XML element ot be send after successful SASL authentication.
         // See XEP-0206 § 5., especially the following is example 5 of XEP-0206.
-        ComposableBody composeableBody = ComposableBody.builder().setNamespaceDefinition("xmpp",
-                        XMPPBOSHConnection.XMPP_BOSH_NS).setAttribute(
-                        BodyQName.createWithPrefix(XMPPBOSHConnection.XMPP_BOSH_NS, "restart",
-                                        "xmpp"), "true").setAttribute(
-                        BodyQName.create(XMPPBOSHConnection.BOSH_URI, "to"), getXMPPServiceDomain().toString()).build();
+        ComposableBody composeableBody = ComposableBody.builder()
+                .setNamespaceDefinition("xmpp", XMPP_BOSH_NS)
+                .setAttribute(BodyQName.createWithPrefix(XMPP_BOSH_NS, "lang", "xmpp"), "en")
+                .setAttribute(BodyQName.createWithPrefix(XMPP_BOSH_NS, "restart", "xmpp"), "true")
+                .setAttribute(BodyQName.create(BOSH_URI, "to"), getXMPPServiceDomain().toString())
+                .build();
 
         try {
             send(composeableBody);
         } catch (BOSHException e) {
             // jbosh's exception API does not really match the one of Smack.
             throw new SmackException.SmackWrappedException(e);
@@ -494,26 +497,29 @@
                     }
                     if (streamId == null) {
                         streamId = body.getAttribute(BodyQName.create(XMPPBOSHConnection.BOSH_URI, "authid"));
                     }
                     final XmlPullParser parser = PacketParserUtils.getParserFor(body.toXML());
 
-                    XmlPullParser.Event eventType = parser.getEventType();
+                    XmlPullParser.Event eventType;
                     do {
                         eventType = parser.next();
                         switch (eventType) {
                         case START_ELEMENT:
                             String name = parser.getName();
                             switch (name) {
                             case Message.ELEMENT:
                             case IQ.IQ_ELEMENT:
+                                // cmeng: temporary fix to init incomingStreamXmlEnvironment for BOSHConnection (no stream:stream)
+                                if ((incomingStreamXmlEnvironment == null) || (incomingStreamXmlEnvironment.getLanguage() == null))
+                                    incomingStreamXmlEnvironment = XmlEnvironment.from(parser);
                             case Presence.ELEMENT:
                                 parseAndProcessStanza(parser);
                                 break;
                             case "features":
-                                parseFeatures(parser);
+                                parseFeaturesAndNotify(parser);
                                 break;
                             case "error":
                                 // Some BOSH error isn't stream error.
                                 if ("urn:ietf:params:xml:ns:xmpp-streams".equals(parser.getNamespace(null))) {
                                     throw new StreamErrorException(PacketParserUtils.parseStreamError(parser));
                                 } else {
