@Override
  public synchronized void loginAnonymously() throws XMPPException {
    if (!isConnected()) {
      throw new IllegalStateException("Not connected to server.");
    }
    if (authenticated) {
      throw new IllegalStateException("Already logged in to server.");
    }

    String response;
    if (config.isSASLAuthenticationEnabled() && saslAuthentication.hasAnonymousAuthentication()) {
      response = saslAuthentication.authenticateAnonymously();
    } else {
      // Authenticate using Non-SASL
      response = new NonSASLAuthentication(this).authenticateAnonymously();
    }

    // Set the user value.
    this.user = response;
    // Update the serviceName with the one returned by the server
    config.setServiceName(StringUtils.parseServer(response));

    // If compression is enabled then request the server to use stream compression
    if (config.isCompressionEnabled()) {
      useCompression();
    }

    // Set presence to online.
    packetWriter.sendPacket(new Presence(Presence.Type.available));

    // Indicate that we're now authenticated.
    authenticated = true;
    anonymous = true;

    // If debugging is enabled, change the the debug window title to include the
    // name we are now logged-in as.
    // If DEBUG_ENABLED was set to true AFTER the connection was created the debugger
    // will be null
    if (config.isDebuggerEnabled() && debugger != null) {
      debugger.userHasLogged(user);
    }
  }
  @Override
  public synchronized void login(String username, String password, String resource)
      throws XMPPException {
    if (!isConnected()) {
      throw new IllegalStateException("Not connected to server.");
    }
    if (authenticated) {
      throw new IllegalStateException("Already logged in to server.");
    }
    // Do partial version of nameprep on the username.
    username = username.toLowerCase().trim();

    // Pause keep alive process while authentication and compression is in
    // progress
    packetWriter.stopKeepAliveProcess();

    String response;
    if (config.isSASLAuthenticationEnabled()
        && saslAuthentication.hasNonAnonymousAuthentication()) {
      // Authenticate using SASL
      if (password != null) {
        response = saslAuthentication.authenticate(username, password, resource);
      } else {
        response = saslAuthentication.authenticate(username, resource, config.getCallbackHandler());
      }
    } else {
      // Authenticate using Non-SASL
      response = new NonSASLAuthentication(this).authenticate(username, password, resource);
    }

    // Set the user.
    if (response != null) {
      this.user = response;
      // Update the serviceName with the one returned by the server
      config.setServiceName(StringUtils.parseServer(response));
    } else {
      this.user = username + "@" + getServiceName();
      if (resource != null) {
        this.user += "/" + resource;
      }
    }

    // If compression is enabled then request the server to use stream compression
    if (config.isCompressionEnabled()) {
      useCompression();
    }

    // Resume keep alive process (after authentication and compression was
    // complited)
    packetWriter.resumeKeepAliveProcess();

    // Indicate that we're now authenticated.
    authenticated = true;
    anonymous = false;

    if (config.isRosterLoadedAtLogin()) {
      // Create the roster if it is not a reconnection or roster already
      // created by getRoster()
      if (this.roster == null) {
        if (rosterStorage == null) {
          this.roster = new Roster(this);
        } else {
          this.roster = new Roster(this, rosterStorage);
        }
      }
      this.roster.reload();
    }

    // Set presence to online.
    if (config.isSendPresence()) {
      packetWriter.sendPacket(new Presence(Presence.Type.available));
    }

    // Stores the authentication for future reconnection
    config.setLoginInfo(username, password, resource);

    // If debugging is enabled, change the the debug window title to include the
    // name we are now logged-in as.
    // If DEBUG_ENABLED was set to true AFTER the connection was created the debugger
    // will be null
    if (config.isDebuggerEnabled() && debugger != null) {
      debugger.userHasLogged(user);
    }
  }