docs: function (req, raw)
      {
          Strophe.info("_dataRecv called");
          var elem = this._proto._reqToData(req);
          if (elem === null) { return; }
  
          if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) {
              if (elem.nodeName === this._proto.strip && elem.childNodes.length) {
                  this.xmlInput(elem.childNodes[0]);
              } else {
                  this.xmlInput(elem);
              }
          }
          if (this.rawInput !== Strophe.Connection.prototype.rawInput) {
              if (raw) {
                  this.rawInput(raw);
              } else {
                  this.rawInput(Strophe.serialize(elem));
              }
          }
  
          // remove handlers scheduled for deletion
          var i, hand;
          while (this.removeHandlers.length > 0) {
              hand = this.removeHandlers.pop();
              i = this.handlers.indexOf(hand);
              if (i >= 0) {
                  this.handlers.splice(i, 1);
              }
          }
  
          // add handlers scheduled for addition
          while (this.addHandlers.length > 0) {
              this.handlers.push(this.addHandlers.pop());
          }
  
          // handle graceful disconnect
          if (this.disconnecting && this._proto._emptyQueue()) {
              this._doDisconnect();
              return;
          }
  
          var type = elem.getAttribute("type");
          var cond, conflict;
          if (type !== null && type == "terminate") {
              // Don't process stanzas that come in after disconnect
              if (this.disconnecting) {
                  return;
              }
  
              // an error occurred
              cond = elem.getAttribute("condition");
              conflict = elem.getElementsByTagName("conflict");
              if (cond !== null) {
                  if (cond == "remote-stream-error" && conflict.length > 0) {
                      cond = "conflict";
                  }
                  this._changeConnectStatus(Strophe.Status.CONNFAIL, cond);
              } else {
                  this._changeConnectStatus(Strophe.Status.CONNFAIL, "unknown");
              }
              this._doDisconnect();
              return;
          }
  
          // send each incoming stanza through the handler chain
          var that = this;
          Strophe.forEachChild(elem, null, function (child) {
              var i, newList;
              // process handlers
              newList = that.handlers;
              that.handlers = [];
              for (i = 0; i < newList.length; i++) {
                  var hand = newList[i];
                  // encapsulate 'handler.run' not to lose the whole handler list if
                  // one of the handlers throws an exception
                  try {
                      if (hand.isMatch(child) &&
                          (that.authenticated || !hand.user)) {
                          if (hand.run(child)) {
                              that.handlers.push(hand);
                          }
                      } else {
                          that.handlers.push(hand);
                      }
                  } catch(e) {
                      // if the handler throws an exception, we consider it as false
                      Strophe.warn('Removing Strophe handlers due to uncaught exception: ' + e.message);
                  }
              }
          });
      }