/**
   * Returns a cloud debugger connection given a user email to indicate the credentials to use. The
   * function may return null if the user is not logged in.
   */
  @Nullable
  private static Debugger getClient(final @Nullable String userEmail, final int timeout) {
    if (Strings.isNullOrEmpty(userEmail)) {
      LOG.warn("unexpected null email in controller initialize.");
      return null;
    }
    final String hashkey = userEmail + timeout;
    Debugger cloudDebuggerClient = myDebuggerClientsFromUserEmail.get(hashkey);

    if (cloudDebuggerClient == null) {
      try {
        final CredentialedUser user = GoogleLogin.getInstance().getAllUsers().get(userEmail);
        final Credential credential = (user != null ? user.getCredential() : null);
        if (credential != null) {
          user.getGoogleLoginState()
              .addLoginListener(
                  new LoginListener() {
                    @Override
                    public void statusChanged(boolean login) {
                      // aggressively remove the cached item on any status change.
                      myDebuggerClientsFromUserEmail.remove(hashkey);
                    }
                  });
          HttpRequestInitializer initializer =
              new HttpRequestInitializer() {
                @Override
                public void initialize(HttpRequest httpRequest) throws IOException {
                  httpRequest.setConnectTimeout(timeout);
                  httpRequest.setReadTimeout(timeout);
                  credential.initialize(httpRequest);
                }
              };

          HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
          cloudDebuggerClient =
              new Builder(httpTransport, JSON_FACTORY, initializer)
                  .setRootUrl(ROOT_URL)
                  .setApplicationName(GoogleLoginUtils.getCurrentPlatformName())
                  .build()
                  .debugger();
        }
      } catch (IOException ex) {
        LOG.warn("Error connecting to Cloud Debugger API", ex);
      } catch (GeneralSecurityException ex) {
        LOG.warn("Error connecting to Cloud Debugger API", ex);
      }

      if (cloudDebuggerClient != null) {
        myDebuggerClientsFromUserEmail.put(hashkey, cloudDebuggerClient);
      }
    }
    return cloudDebuggerClient;
  }
  @Override
  protected ValidationInfo doValidate() {
    // These should not normally occur.
    if (!GoogleLogin.getInstance().isLoggedIn()) {
      return new ValidationInfo(GctBundle.getString("clouddebug.nologin"));
    }

    if (Strings.isNullOrEmpty(myElysiumProjectId.getText())) {
      return new ValidationInfo(GctBundle.getString("clouddebug.noprojectid"));
    }

    if (myDebuggeeTarget.getSelectedItem() == null) {
      return new ValidationInfo(GctBundle.getString("clouddebug.nomodule"));
    }

    return null;
  }