/**
   * Performs this <tt>AsyncContactQuery</tt> in a background <tt>Thread</tt>.
   *
   * @see AsyncContactQuery#run()
   */
  @Override
  protected void run() {
    GoogleContactsServiceImpl service = GoogleContactsActivator.getGoogleContactsService();
    gQuery = new GoogleQuery(query);

    GoogleContactsConnection cnx = getContactSource().getConnection();

    if (cnx == null) {
      return;
    }

    service.searchContact(
        cnx,
        gQuery,
        count,
        new GoogleEntryCallback() {
          public void callback(GoogleContactsEntry entry) {
            onGoogleContactsEntry(entry);
          }
        });
  }
  /**
   * Returns the Google Contacts connection.
   *
   * @return Google Contacts connection
   */
  public GoogleContactsConnectionImpl getConnection() {
    int s = login.indexOf('@');
    boolean isGoogleAppsOrGmail = false;

    if (s == -1) {
      return null;
    }

    String domain = login.substring((s + 1));

    try {
      SRVRecord srvRecords[] = NetworkUtils.getSRVRecords("xmpp-client", "tcp", domain);

      if (srvRecords != null) {
        // To detect that account is a google ones, we try following:
        // - lookup in SRV and see if it is google.com;
        // - if the account has been created with GoogleTalk form;
        // - if it is an "external" google contact.

        // SRV checks
        for (SRVRecord srv : srvRecords) {
          if (srv.getTarget().endsWith("google.com") || srv.getTarget().endsWith("google.com.")) {
            isGoogleAppsOrGmail = true;
            break;
          }
        }
      }

      // GoogleTalk based account or external Google Contacts ?
      if (!isGoogleAppsOrGmail) {
        isGoogleAppsOrGmail = googleTalk;
      }

      if (isGoogleAppsOrGmail) {
        if (cnx == null) {
          cnx = new GoogleContactsConnectionImpl(login, password);

          if (cnx.connect()
              == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) {
            synchronized (this) {
              if (settings != null) {
                cnx = null;
                return null;
              } else {
                settings = new AccountSettingsForm();
              }
            }
            settings.setModal(true);
            settings.loadData(cnx);
            int ret = settings.showDialog();

            if (ret == 1) {
              cnx = settings.getConnection();
              GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx);
            } else {
              cnx = null;
            }
          }
        } else if (cnx.connect()
            == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) {
          synchronized (this) {
            if (settings != null) {
              cnx = null;
              return null;
            } else {
              settings = new AccountSettingsForm();
            }
          }
          settings.setModal(true);
          settings.loadData(cnx);
          int ret = settings.showDialog();

          if (ret == 1) {
            cnx = settings.getConnection();
            GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx);
          } else {
            cnx = null;
          }
        }
      } else {
        cnx = null;
      }
    } catch (Exception e) {
      logger.info("GoogleContacts connection error", e);
      return null;
    }

    return (GoogleContactsConnectionImpl) cnx;
  }