docs: function (matched)
      {
        var i;
        // Sorting matched mechanisms according to priority.
        for (i = 0; i < matched.length - 1; ++i) {
          var higher = i;
          for (var j = i + 1; j < matched.length; ++j) {
            if (matched[j].prototype.priority > matched[higher].prototype.priority) {
              higher = j;
            }
          }
          if (higher != i) {
            var swap = matched[i];
            matched[i] = matched[higher];
            matched[higher] = swap;
          }
        }
  
        // run each mechanism
        var mechanism_found = false;
        for (i = 0; i < matched.length; ++i) {
          if (!matched[i].test(this)) continue;
  
          this._sasl_success_handler = this._addSysHandler(
            this._sasl_success_cb.bind(this), null,
            "success", null, null);
          this._sasl_failure_handler = this._addSysHandler(
            this._sasl_failure_cb.bind(this), null,
            "failure", null, null);
          this._sasl_challenge_handler = this._addSysHandler(
            this._sasl_challenge_cb.bind(this), null,
            "challenge", null, null);
  
          this._sasl_mechanism = new matched[i]();
          this._sasl_mechanism.onStart(this);
  
          var request_auth_exchange = $build("auth", {
            xmlns: Strophe.NS.SASL,
            mechanism: this._sasl_mechanism.name
          });
  
          if (this._sasl_mechanism.isClientFirst) {
            var response = this._sasl_mechanism.onChallenge(this, null);
            request_auth_exchange.t(Base64.encode(response));
          }
  
          this.send(request_auth_exchange.tree());
  
          mechanism_found = true;
          break;
        }
  
        if (!mechanism_found) {
          // if none of the mechanism worked
          if (Strophe.getNodeFromJid(this.jid) === null) {
              // we don't have a node, which is required for non-anonymous
              // client connections
              this._changeConnectStatus(Strophe.Status.CONNFAIL,
                                        'x-strophe-bad-non-anon-jid');
              this.disconnect('x-strophe-bad-non-anon-jid');
          } else {
            // fall back to legacy authentication
            this._changeConnectStatus(Strophe.Status.AUTHENTICATING, null);
            this._addSysHandler(this._auth1_cb.bind(this), null, null,
                                null, "_auth_1");
  
            this.send($iq({
              type: "get",
              to: this.domain,
              id: "_auth_1"
            }).c("query", {
              xmlns: Strophe.NS.AUTH
            }).c("username", {}).t(Strophe.getNodeFromJid(this.jid)).tree());
          }
        }
  
      }